Группы процессов

Группы процессов позволяют процессам вступать в именованные группы и получать широковещательные сообщения, адресованные группе, с отслеживанием членства на каждой ноде кластера. Модель следует Erlang/OTP pg: группы создаются при первом вступлении, процесс может принадлежать многим группам (и вступать в одну группу несколько раз), и нет центрального реестра — каждая нода поддерживает состояние и согласовывает его с пирами через gossip.

Lua API задокументирован в Группах процессов; эта страница описывает тип записи scope и его конфигурацию. Окружающую модель membership см. в Руководстве по кластеру.

Тип записи

Тип Описание
pg.scope Независимое пространство имён групп процессов с собственным состоянием членства и кластерным мешем

Каждая область изолирована: группы и члены одной области невидимы в другой. Процесс открывает область по её entry ID (pg.open("app:pg")) и работает внутри неё.

- name: pg
  kind: pg.scope
  lifecycle:
    auto_start: true

Конфигурация

Все поля опциональны и имеют значения по умолчанию, настроенные для типичного кластера.

Поле Тип По умолчанию Описание
protocol_timeout duration 5s Таймаут для операций межнодовой синхронизации/обнаружения
broadcast_timeout duration 5s Таймаут доставки broadcast одному члену
anti_entropy_interval duration 30s Период цикла согласования; один пир синхронизируется за тик (0 отключает)
circuit_breaker_failures int 3 Последовательных ошибок отправки ноде до открытия автоматического выключателя
circuit_breaker_reset_time duration 10s Ожидание до перехода открытого автоматического выключателя в полуоткрытое состояние для тестовой отправки
max_retries int 3 Попыток повтора при неудачном broadcast (0 отключает повторы)
retry_base_delay duration 100ms Начальная задержка отступа между повторами
retry_max_delay duration 1s Максимальная задержка отступа
action_queue_size int 256 Глубина, при которой логируется предупреждение "approaching capacity"
action_queue_max_size int 1024 Жёсткая ёмкость внутренней очереди event loop; операции отбрасываются при заполнении
monitor_buffer int 64 Ёмкость канала событий на подписку; события отбрасываются для подписчика с заполненным буфером
max_groups int 0 Максимум различных групп (0 = без ограничений)
max_members_per_group int 0 Максимум членов на группу с учётом multi-join (0 = без ограничений)
- name: pg
  kind: pg.scope
  anti_entropy_interval: 30s
  circuit_breaker_failures: 3
  max_members_per_group: 10000
  lifecycle:
    auto_start: true

Как это работает

Состояние с единственным писателем. Каждая область запускает однопоточный event loop (паттерн gen_server). Все мутации сериализуются через него; чтения членов и групп обслуживаются из атомарно публикуемых снимков, поэтому они никогда не блокируют loop.

Распространение join/leave. Локальное join или leave применяется к loop и затем рассылается объединению живых пиров membership и ранее обнаруженных удалённых нод. Отправка в это объединение — а не только в пиры, обнаруженные gossip — гарантирует, что свежеприсоединившаяся или ещё не сошедшаяся нода всё равно получит изменение.

Broadcast. broadcast делает снимок полного кросс-кластерного списка членов внутри loop, затем доставляет каждому члену вне loop, чтобы медленный получатель не мог заблокировать область. broadcast_local делает то же самое, но только для членов на локальной ноде.

Monitor и events. Подписка и получение снимка текущих членов происходят за один тик event loop, поэтому подписчик никогда не пропустит и не посчитает дважды изменение, гонящееся с подпиской. Подписчики получают события member.joined / member.left; leave для процесса, вступившего N раз, сообщает PID N раз, сохраняя кратность.

Anti-entropy и обнаружение. При запуске область отправляет сообщения обнаружения небольшому случайному подмножеству пиров (с ограничением, чтобы избежать N²-шторма при массовом перезапуске нод). При вступлении ноды она получает полную синхронизацию состояния. Цикл anti-entropy периодически отправляет полную синхронизацию одному пиру за раз, чтобы любой пропущенный broadcast в конечном счёте сошёлся. Получатель применяет дифференциальную синхронизацию — только фактически добавленные или удалённые члены генерируют события.

Автоматические выключатели. Per-node автоматический выключатель отслеживает последовательные ошибки отправки. После circuit_breaker_failures ошибок он открывается и отправки этой ноде пропускаются до истечения circuit_breaker_reset_time, когда разрешается одна тестовая отправка. Broadcast join/leave, попавшие на открытый выключатель, повторяются с экспоненциальным отступом до max_retries раз.

Наблюдаемость

Проверка готовности (pg.broadcast_recent.<scope>) сообщает о неработоспособности если область не видит broadcast-трафика длительное время, что сигнализирует о заблокированном event loop или устойчивом разделении. См. Руководство по наблюдаемости.

Смотрите также