Поддержание 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. Чтобы объяснить проблему, я описал пример следующим образом:
Пример:
- Я хотел бы начать публиковать события в SQS вместо Sidekiq с t=0.
- Затем я хотел бы, чтобы события, поставленные в очередь в Sidekiq до t=0, обрабатывались по порядку, и только после этого мы должны начинать обработку событий из очереди SQS.
- Предположим, мы перезапускаем все серверы Puma вместе, Puma 1 завершает перезапуск первым и публикует событие в SQS, но к этому времени по какой-то причине Puma 2 еще не перезапустился и отправляет последующее событие в Sidekiq.
Как этого избежать?
Любая помощь или предложение приветствуются. Заранее спасибо!
2 ответа
В итоге я выполнил миграцию с Sidekiq на Shoryuken с помощью двух последующих развертываний и двух флагов/конфигураций. Решение, предложенное user11711477 , также во многом похоже на мое, я просто добавил еще несколько шагов, чтобы обеспечить порядок обработки моих событий FIFO. Всю миграцию с Sidekiq-Redis на Shoryuken-SQS(FIFO) для обработки событий в порядке FIFO можно выполнить, выполнив указанные ниже шаги по порядку:
Развертывание 1. Разверните для запуска/остановки отправки событий в любую очередь (Sidekiq или SQS). Обратите внимание, что у нас должна быть резервная копия создаваемых событий, чтобы это работало. В нашем случае мы уже сохраняли созданные события в
events
таблицу в нашей БД перед отправкой.Выключить . Допустим, мы выключили его после отправки события с id=100.
Продолжайте сохранять в Redis идентификаторы событий всех неотправленных событий во флаге с именем .
Подождите, пока все события, которые уже были поставлены в очередь в Sidekiq, будут обработаны. (т.е. до event_id=100).
Развертывание 2. Развертывание кода SQS. Изменения в коде передают события в SQS, а не в Sidekiq. А также второй конфиг - (выключен). Это сообщит обработчику Shoryuken, разрешено ли ему успешно обрабатывать события из SQS. Когда он отключен, Shoryuken должен вызывать исключение и оставаться в цикле повторных попыток первого события в SQS. Обратите внимание, что использование событий во время публикации также должно присутствовать в коде.
Убедитесь, что выключен, а затем включите
Publish Enabled Config
- Начинает отправлять события в SQS. Допустим, мы включили его после создания события с id=150.Обрабатывать промежуточные события, которые не были помещены в какую-либо очередь (ни Sidekiq, ни SQS) — идентификаторы событий, сохраненные во флаге Redis —
unprocessed_event_ids
- Запустите скрипт для обработки этих событий по порядку. В нашем примере это будут события от event_id=101 до event_id=150.Включите
Processing Via Shoryuken Enabled Config
- Запускает обработку событий от SQS.Миграция завершена. Очистите ненужные конфигурации/флаги с помощью другого развертывания в любое время в будущем, если и когда это потребуется.
Вот как я справился с миграцией обработки событий FIFO с Sidekiq-Redis на Shoryuken-SQS (FIFO) без простоев. Любые предложения или отзывы приветствуются.
Спасибо!
Просто наивная мысль: чтобы гарантировать, что никакие задания Sidekiq не будут поставлены в очередь после того, как задание SQS поставлено в очередь, вы можете просто установить флаг (в Redis) после того, как задание SQS поставлено в очередь, чтобы предотвратить помещение заданий Sidekiq в очередь.
Итак, вам понадобятся два развертывания:
- Добавьте флаг + логику, чтобы предотвратить push-уведомления Sidekiq.
- Добавьте материал SQS + логику, которая устанавливает флаг
Обратите внимание, что это не гарантирует, что ваше задание Sidekiq не завершится после первого задания SQS.