从 Sidekiq 转移到 Shoryuken 时保持 FIFO

Maintaining FIFO while moving from Sidekiq to Shoryuken

我们目前正在 Rails 应用程序中使用 Sidekiq 中的队列以 FIFO 顺序执行事件处理。由于某些原因 - 成本和其他一些好处 - 我们正在从 Sidekiq 转移到 Shoryuken(使用 SQS FIFO 队列)。

目前,我们正在 concurrency: 1 使用 Sidekiq worker,以便它一次处理一个作业并保持 FIFO 顺序。

迁移到 Shoryuken 后,SQS FIFO 队列也会为我们处理这个问题。

我的问题是这样 - 如何在不停机的情况下从 Sidekiq 迁移到 Shoryuken,同时保持事件处理的 FIFO 顺序。有 5 个并行 Rails Puma 实例将事件发布到 Sidekiq 或将发布到 SQS。同时重新启动所有 5 个事件并不能确保在至少有一个事件发布到 SQS 后,没有事件会发布到 Sidekiq。为了解释这个问题,我描述了一个例子如下:

示例

  1. 我想从 t=0 开始将事件发布到 SQS 而不是 Sidekiq。
  2. 然后我希望在 t=0 之前在 Sidekiq 中排队的事件应该按顺序处理,然后我们才应该开始处理来自 SQS 队列的事件。
  3. 假设我们一起重启所有的Puma服务器,Puma 1先重启完成并发布一个事件到SQS,但是此时由于某种原因Puma 2还没有重启并推送一个后续事件到Sidekiq。

如何避免这种情况?

感谢任何形式的帮助或建议。提前致谢!

只是一个幼稚的想法: 为了确保 SQS 作业入队后没有 Sidekiq 作业入队,您可以在 SQS 作业入队后简单地设置一个标志(在 Redis 中)以防止任何 Sidekiq 作业入队。

因此您需要两次部署:

  1. 添加标志+逻辑以防止 Sidekiq 推送
  2. 添加 SQS 内容 + 设置标志的逻辑

请注意,这并不能确保您的 Sidekiq 作业不会在您的第一个 SQS 作业后完成。

在 2 个后续部署和 2 个 flags/configs 的帮助下,我最终完成了从 Sidekiq 到 Shoryuken 的迁移。 Kenneth 建议的解决方案也与我的大致相似,我只是添加了几个步骤以确保事件处理的 FIFO 顺序。从 Sidekiq-Redis 到 Shoryuken-SQS(FIFO) 以 FIFO 顺序处理事件的整个迁移可以通过按顺序执行以下提到的步骤来执行:

  1. 部署 1 - 部署 Publish Enabled Config 到 start/stop 将事件推送到任何队列(Sidekiq 或 SQS)。请注意,我们必须对正在创建的事件进行备份才能使其正常工作。在我们的例子中,我们已经在推送之前将创建的事件保存在数据库中的 events table 中。

  2. 关闭Publish Enabled Config。假设我们在推送 id=100 的事件后将其关闭。

  3. 继续在 Redis 中保存所有 un-pushed 事件的 event_ids,在一个名为 unprocessed_event_ids.

    的标志中
  4. 等待所有已经在Sidekiq排队的事件处理完毕。 (即,直到 event_id=100)。

  5. 部署 2 - 部署 SQS 代码 - 将事件推送到 SQS 而不是 Sidekiq 的代码更改。还有第二个配置 - Processing Via Shoryuken Enabled Config(关闭)。这将告知 Shoryuken worker 是否允许成功处理来自 SQS 的事件。当它关闭时,Shoryuken 应该引发异常并停留在 SQS 中第一个事件的重试循环中。请注意,在发布事件时使用 Publish Enabled Config 也应该在代码中。

  6. 确保 Processing Via Shoryuken Enabled Config 关闭,然后打开 Publish Enabled Config - 开始将事件推送到 SQS。假设我们在创建 id=150 的事件后将其打开。

  7. 处理没有被推送到任何队列(既不是Sidekiq也不是SQS)的中间事件 - event_ids保存在Redis的flag中 - unprocessed_event_ids - 运行 a脚本按顺序处理这些事件。在我们的示例中,这些事件将从 event_id=101 到 event_id=150.

  8. 打开 Processing Via Shoryuken Enabled Config - 开始处理来自 SQS 的事件。

  9. 迁移完成。通过另一个部署清理不必要的 configs/flags,在未来的任何时候,如果需要的话。

这就是我如何处理 FIFO 事件处理从 Sidekiq-Redis 到 Shoryuken-SQS(FIFO) 的迁移,没有任何停机时间。感谢任何建议或反馈。

谢谢!