Подтвердить что ты не робот

Как атомизировать обновление счетчика, разделяемого между экземплярами Docker

У меня есть простая служба С++ (конечная точка API), которая увеличивает счетчик каждый раз, когда вызывается API. Когда вызывающий абонент отправляет данные в http://10.0.0.1/add, счетчик должен увеличиваться на 1 и возвращать значение счетчика вызывающему.

Все становится сложнее, когда служба получает докеры. Когда два экземпляра одного и того же сервиса запускаются, добавление должно выполняться атомарно, то есть значение счетчика сохраняется в базе данных, и каждый экземпляр докера должен получить блокировку, получить старое значение, добавить один, вернуться к вызывающей стороне и разблокировать.

Когда экземпляры являются процессами на одной машине Linux, мы использовали общую память для эффективной блокировки, чтения, записи и разблокировки общих данных, и производительность была принята. Однако, когда мы используем докеры и базу данных, производительность низкая. Результаты в порядке, однако производительность низкая.

Каков канонический путь между экземплярами докционированных свойств для выполнения операций, подобных описанным выше? Есть ли функция "разделяемой памяти" для контейнерных процессов?

4b9b3361

Ответ 2

Параметр --ipc docker run обеспечивает доступ к общей памяти между контейнерами:

Настройки IPC (-ipc)

--ipc="": установите режим IPC для контейнера,

'container:<name|id>': повторное использование другого пространства имен IPC контейнера

'host': используйте пространство имен IPC хоста внутри контейнера

По умолчанию все контейнеры имеют пространство имен IPC.

Пространство имен IPC (POSIX/SysV IPC) обеспечивает разделение именованных общих сегменты памяти, семафоры и очереди сообщений.

Общие сегменты памяти используются для ускорения межпроцессного взаимодействия связь на скорости памяти, а не через трубы или через сетевой стек. Общая память обычно используется базами данных и (как правило, C/OpenMPI, С++/с использованием библиотек boost) приложений для научных вычислений и финансовых услуг. Если эти типы приложений разбиты на вам может потребоваться совместное использование механизмов IPC для контейнеры.

В этой статье представлена ​​некоторая демонстрация ее использования.

Ответ 3

У меня возникла аналогичная проблема, и я решил загнать ее в голову.

Единственное, что происходит быстро, это сокеты домена. Поэтому я создал небольшую c-программу, которая прослушивает сокет домена, в общем томе/сокетах.

см. рабочую концепцию test на gitlab.com.

counter.c выполняет эту работу, слушает сокеты /count.sock и при получении единственного char в дейтаграмме:

  • '+': он увеличит счетчик и вернет счет как u_int64_t
  • '0': сбрасывает счетчик и возвращает значение 0 как u_int64_t
  • '=': возвращает счетчик как u_int64_t без приращения
  • '-': число декрементов с одним и возвращает count как u_int64_t

для тестирования концепции:

  • counter --interval=1000000 = > запускает счетчик
  • test_counter --repeats=100000 stress = > отправляет запрос 100k в сокет
  • test_counter reset установить счетчик 0
  • test_counter --quiet --strip result возвращает счетчик без \n
  • test_counter [count] увеличивает счетчик и возвращает результат.

2 контейнера докеров собраны: count и test repo

и для тестирования я использовал docker-compose.yml в 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}

чтобы начать тест:

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

Полноценный тест на тестирование!!! см. тестовое задание

cavecat:

для реализации клиента клиентский сокет не может быть привязан как автоматический, но ему нужно дать имя, см. в тесте мы используем имя хоста, отображаемое в том же томе/сокетах. Также они должны быть разными для каждого клиента.