Поддержание FIFO при переходе с Sidekiq на Shoryuken

В настоящее время мы выполняем обработку событий в порядке FIFO в нашем приложении Rails, используя очередь в Sidekiq. По ряду причин — стоимости и некоторых других преимуществ — мы переходим с Sidekiq на Shoryuken(с очередью SQS FIFO).

В настоящее время мы используем воркер Sidekiq в concurrency: 1так что он обрабатывает одно задание за раз и поддерживает порядок FIFO.

SQS FIFO Queue также справится с этим после перехода на Shoryuken.

Моя проблема заключается в следующем - Как мне перейти с Sidekiq на Shoryuken без простоев, но в то же время сохранить порядок обработки моих событий FIFO. Существует 5 параллельных экземпляров Rails Puma, которые публикуют события в Sidekiq или в SQS. Перезапуск всех 5 из них одновременно не гарантирует, что ни одно событие не будет опубликовано в Sidekiq после того, как хотя бы одно событие будет опубликовано в SQS. Чтобы объяснить проблему, я описал пример следующим образом:

Пример:

  1. Я хотел бы начать публиковать события в SQS вместо Sidekiq с t=0.
  2. Затем я хотел бы, чтобы события, поставленные в очередь в Sidekiq до t=0, обрабатывались по порядку, и только после этого мы должны начинать обработку событий из очереди SQS.
  3. Предположим, мы перезапускаем все серверы Puma вместе, Puma 1 завершает перезапуск первым и публикует событие в SQS, но к этому времени по какой-то причине Puma 2 еще не перезапустился и отправляет последующее событие в Sidekiq.

Как этого избежать?

Любая помощь или предложение приветствуются. Заранее спасибо!

2 ответа

В итоге я выполнил миграцию с Sidekiq на Shoryuken с помощью двух последующих развертываний и двух флагов/конфигураций. Решение, предложенное user11711477 , также во многом похоже на мое, я просто добавил еще несколько шагов, чтобы обеспечить порядок обработки моих событий FIFO. Всю миграцию с Sidekiq-Redis на Shoryuken-SQS(FIFO) для обработки событий в порядке FIFO можно выполнить, выполнив указанные ниже шаги по порядку:

  1. Развертывание 1. Разверните для запуска/остановки отправки событий в любую очередь (Sidekiq или SQS). Обратите внимание, что у нас должна быть резервная копия создаваемых событий, чтобы это работало. В нашем случае мы уже сохраняли созданные события в eventsтаблицу в нашей БД перед отправкой.

  2. Выключить . Допустим, мы выключили его после отправки события с id=100.

  3. Продолжайте сохранять в Redis идентификаторы событий всех неотправленных событий во флаге с именем .

  4. Подождите, пока все события, которые уже были поставлены в очередь в Sidekiq, будут обработаны. (т.е. до event_id=100).

  5. Развертывание 2. Развертывание кода SQS. Изменения в коде передают события в SQS, а не в Sidekiq. А также второй конфиг - (выключен). Это сообщит обработчику Shoryuken, разрешено ли ему успешно обрабатывать события из SQS. Когда он отключен, Shoryuken должен вызывать исключение и оставаться в цикле повторных попыток первого события в SQS. Обратите внимание, что использование событий во время публикации также должно присутствовать в коде.

  6. Убедитесь, что выключен, а затем включите Publish Enabled Config- Начинает отправлять события в SQS. Допустим, мы включили его после создания события с id=150.

  7. Обрабатывать промежуточные события, которые не были помещены в какую-либо очередь (ни Sidekiq, ни SQS) — идентификаторы событий, сохраненные во флаге Redis — unprocessed_event_ids- Запустите скрипт для обработки этих событий по порядку. В нашем примере это будут события от event_id=101 до event_id=150.

  8. Включите Processing Via Shoryuken Enabled Config- Запускает обработку событий от SQS.

  9. Миграция завершена. Очистите ненужные конфигурации/флаги с помощью другого развертывания в любое время в будущем, если и когда это потребуется.

Вот как я справился с миграцией обработки событий FIFO с Sidekiq-Redis на Shoryuken-SQS (FIFO) без простоев. Любые предложения или отзывы приветствуются.

Спасибо!

Просто наивная мысль: чтобы гарантировать, что никакие задания Sidekiq не будут поставлены в очередь после того, как задание SQS поставлено в очередь, вы можете просто установить флаг (в Redis) после того, как задание SQS поставлено в очередь, чтобы предотвратить помещение заданий Sidekiq в очередь.

Итак, вам понадобятся два развертывания:

  1. Добавьте флаг + логику, чтобы предотвратить push-уведомления Sidekiq.
  2. Добавьте материал SQS + логику, которая устанавливает флаг

Обратите внимание, что это не гарантирует, что ваше задание Sidekiq не завершится после первого задания SQS.

Другие вопросы по тегам