Эффективная эксклюзивная блокировка с ZooKeeper для редких операций - PullRequest
1 голос
/ 24 января 2020

Я развернул микро-сервис на нескольких серверах, который имеет два основных источника данных:

  1. События, полученные постоянно (24/7/365) в большом объеме (100- 1000 событий / сек c)

  2. Операция раз в день, которая может занять мгновение до конца sh

Я хочу чтобы запустить эту обработку один раз в день в монопольном режиме: приостановите обработку событий, запустите задачу один раз в день, а затем возобновите обработку событий. У меня уже есть способ правильно запустить однократную операцию, но мне все еще нужно реализовать блокировку между 1 и 2. Чтобы обеспечить исключительность.

Большинство рецептов ZooKeeper, которые я обнаружил, требуют операции записи для каждого обработанного события например, захват блокировки чтения с InterProcessReadWriteLock или увеличение счетчика с DistributedAtomicLong. Поскольку ежедневные операции случаются нечасто, эти издержки для каждого события кажутся бесполезными.

Есть ли квитанция ZooKeeper / Curator, оптимизированная для такого случая использования?

Я думал о следующем, но я Я не на 100% уверен, что это правильный подход (и как реализовать пункт 2 ниже):

  1. Когда начинается ежедневная операция, создайте новый путь /exclusive в ZooKeeper
  2. Дождитесь окончания всех событий в полете sh
  3. Перед обработкой события проверьте, существует ли /exclusive. Если он есть, прекратите обработку до тех пор, пока /exclusive путь не будет удален
  4. По окончании одного раза в день удалите путь /exclusive

1 Ответ

1 голос
/ 26 января 2020

Как насчет этого?

Каждый обработчик событий должен:

  • получить блокировку read через InterProcessReadWriteLock .
  • Используйте NodeCache для просмотра узла "сигнала" и прослушивания изменений на этом узле. Когда узел существует, это означает, что это ежедневное время обработки. Когда он не существует, обработка события может продолжаться.
  • Когда NodeCache показывает, что узел сигнала создан, обработчики событий должны снять свои блокировки и дождаться удаления узла сигнала (снова путем прослушивания с помощью NodeCache).
  • Когда NodeCache показывает, что сигнальный узел был удален, обработчики событий снова получают блокировки чтения и продолжают обрабатывать события.

Как только это установлено, дополнительная активность ZooKeeper не выполняется, пока она все работает.

Когда готовая к запуску операция раз в день:

  • Создает сигнальный узел (как эфемерный узел)
  • Получает запись блокировка по тому же пути, который используют процессоры событий для своих блокировок чтения
  • выполняет свою периодическую обработку c обработка
  • снимает блокировку записи
  • удаляет сигнальный узел

Однако с этим связано огромное предостережение, и именно это может произойти с паузами JVM. Пожалуйста, прочтите также это Техническое примечание для важных крайних случаев.

...