使用 LPUSH
和 BRPOPLPUSH
( http://redis.io/commands/rpoplpush ) 在 Redis 中实现持久队列是一种众所周知的模式。然而,为了扩大规模,该设计需要满足主任务队列中 BRPOPLPUSH
的多个工作人员/消费者。
所以规范似乎是对于每个工作人员都有一个单独的 processing_queue
记录特定工作人员正在处理的任务,这样工作人员可以跟踪剩下要做的事情以防万一它在处理过程中退出。
关于这个 processing_queue
我有两个问题:
worker 的
processing_queue
中任何时候都最多一个 项/任务的推理是否正确?我假设工作人员首先检查其自己的processing_queue
中的任何遗留任务,然后再检查主任务队列的BRPOPLPUSH
。如果是这样,我们可以使用RPOP
、LPOP
、LREM
中的任何一个在 worker 完成处理后删除任务(或者它可以简单地删除列表)。我们甚至可以使用集合而不是列表。为什么这么多人选择使用LREM
而没有别的原因?我看到很多人建议使用相应工作进程的进程 ID 来识别个体
processing_queue
。但是当旧的 worker 退出并且使用(最有可能的)新进程 ID 产生新的 worker 时会发生什么。新工作人员如何查找其前任的processing_queue
以完成可能遗留的任务?我计划使用Supervisor
来管理我的工作进程,如果这有影响的话。
最佳答案
视情况而定。如果您只想让工作人员从主队列中拉出一份工作,处理它,冲洗并重复然后是。然而,这不是一个硬性要求,而是一种设计选择。例如,当您想要序列化从主要任务派生的作业时,您可以让工作人员将其他项目推送到
processing_queue
。我对
Supervisor
不熟悉,但您可以保留一个单独的数据结构 - 在这里最好使用排序集 - 将您的工作人员的标识符作为元素,将时间戳记作为他们的分数.让你的员工定期更新他们的时间戳,当你启动一个新的员工时,让它检查那些闲置时间太长的员工。当找到这样的东西时,尝试确定它实际上已经死了,然后让新的工作人员接管相关的processing_queue
(例如,使用RENAME
)。
关于design-patterns - Redis中持久队列的 worker 管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30855571/