tag hub linux performance docker shared-memory

linux - hub - Cómo actualizar atómicamente un contador compartido entre instancias de Docker



docker hub (3)

Tengo un servicio C ++ simple (punto final API) que aumenta un contador cada vez que se llama a la API. Cuando la persona que llama publica datos en http://10.0.0.1/add, el contador debe incrementarse en 1 y devolver el valor del contador a la persona que llama.

Las cosas se vuelven más complicadas cuando el servicio está siendo encajado. Cuando se ejecutan dos instancias del mismo servicio, la adición tiene que hacerse atómicamente, es decir, el valor del contador se almacena en una base de datos y cada instancia de acoplador debe adquirir un bloqueo obtener el valor anterior, agregar uno, regresar al llamador y desbloquearse.

Cuando las instancias son procesos en la misma máquina Linux, utilizamos la memoria compartida para bloquear, leer, escribir y desbloquear eficientemente los datos compartidos y se aceptó el rendimiento. Sin embargo, cuando usamos estibadores y una base de datos, el rendimiento es bajo. Los resultados están bien, sin embargo, el rendimiento es bajo.

¿Cuál es la forma canónica entre instancias de propiedades dockerized para realizar operaciones como la descrita anteriormente? ¿Hay una función de "memoria compartida" para los procesos en contenedores?



La opción --ipc de docker run habilita el acceso a memoria compartida entre contenedores:

Configuración de IPC (--ipc)

--ipc="" : configura el modo IPC para el contenedor,

''container:<name|id>'' : reutiliza el espacio de nombres IPC de otro contenedor

''host'' : use el espacio de nombres IPC del host dentro del contenedor

Por defecto, todos los contenedores tienen habilitado el espacio de nombres IPC.

El espacio de nombres IPC (POSIX / SysV IPC) proporciona la separación de segmentos de memoria compartida nombrados, semáforos y colas de mensajes.

Los segmentos de memoria compartida se usan para acelerar la comunicación entre procesos a la velocidad de la memoria, en lugar de a través de las tuberías o a través de la pila de la red. La memoria compartida es comúnmente utilizada por las bases de datos y las aplicaciones personalizadas (generalmente C / OpenMPI, C ++ / using boost libraries) de alto rendimiento para la informática científica y las industrias de servicios financieros. Si estos tipos de aplicaciones se dividen en varios contenedores, es posible que deba compartir los mecanismos de IPC de los contenedores.

Este artículo proporciona alguna demostración de su uso.


Estaba enfrentando un problema similar y decidí investigarlo.

Lo único que pasa rápido son los sockets de dominio. Así que creé un pequeño c-programa que escucha en un socket de dominio, en un volumen / sockets compartidos.

ver un concepto de trabajo en prueba en gitlab.com.

counter.c hace el trabajo, escucha en sockets / count.sock y al recibir un solo carácter en un datagrama:

  • ''+'': aumentará el conteo y devolverá el conteo como u_int64_t
  • ''0'': restablece el recuento y devuelve el valor 0 como u_int64_t
  • ''='': devuelve el recuento como u_int64_t, sin incremento
  • ''-'': decremento cuenta con uno y devuelve conteo como u_int64_t

para la prueba de concepto:

  • counter --interval=1000000 => inicia el contador
  • test_counter --repeats=100000 stress => indica 100k petición al socket
  • test_counter reset el contador del conjunto a 0
  • test_counter --quiet --strip result devuelve el contador sin /n
  • test_counter [count] incrementa el contador y devuelve el resultado.

Se construyen 2 contenedores docker: count y test

y para probar, utilicé docker-compose.yml en un gitlab-runner:

my-test: image: dockregi.gioxa.com/dgoo2308/dockersocket:test links: - counter entrypoint: - /test_counter - --repeats=${REPEATS} - --timeout=200 - stress volumes: - ''./sockets:/sockets'' counter: image: dockregi.gioxa.com/dgoo2308/dockersocket:count volumes: - ''./sockets:/sockets'' entrypoint: - /counter - --start_delay=100 - --interval=${TARGET}

para comenzar la prueba:

mkdir sockets docker-compose pull --parallel docker-compose up -d docker-compose scale my-test=$SCALE

Prueba de concepto de éxito completo !!! ver prueba Job

cavecat:

para la implementación del cliente, el socket del cliente no puede vincularse como automático, sino que necesita un nombre, ver en la prueba que usamos el nombre del servidor, mapeado en el mismo volumen / sockets. También deben ser diferentes para cada cliente.