跳到主要内容
英文版本为准

本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。

队列

可靠列表在处理器运行之前把每个条目移到处理中列表,处理器结算时再把它从那里移除。

可靠列表:认领把条目移到处理中列表,结果在那里结算它,恢复集合把无主的条目送回队列生产者jobsjobs.processing恢复集合按认领时间排序处理器ack:LREMretry:LPUSH推回,再 LREMdrop:LREM每次读取先把空闲超过 min_idle 的认领送回队列
以文字阅读本图
  1. 生产者 → jobs: LPUSH
  2. jobs → jobs.processing: BLMOVE
  3. jobs.processing → 处理器: 投递
  4. jobs.processing → 恢复集合 按认领时间排序: ZADD
  5. 恢复集合 按认领时间排序 → jobs: 送回无主条目
  6. 处理器 → ack: LREM
  7. 处理器 → retry:LPUSH 推回,再 LREM
  8. 处理器 → drop: LREM
  9. 每次读取先把空闲超过 min_idle 的认领送回队列

列表是一个队列:LPUSH 从一端加入,弹出从另一端取,最早的条目最先离开。弹出的条目就从 Redis 中消失了。简单的 RedisList 用 BRPOP 弹出,因此处理器失败或进程死掉时,条目就丢失了:投递是至多一次。

可靠列表用认领代替弹出。BLMOVE 用一条命令把条目从队列移到处理中列表,处理器运行期间条目一直留在那里。处理中列表默认是 <key>.processing,订阅也可以指定别的名字。结果在处理中列表上结算条目:LREM 移除它,重试则先把它推回队列。投递是至少一次。Redis 在 LMOVE 下描述了这一模式。

列表不记录谁在何时取走了条目,因此消费者在认领之后死掉,条目就留在处理中列表上。recovery_zset 保存这份记录。每次认领都加入一个有序集合,以认领时间为分值。每次读取先清扫早于 min_idle 的认领,用 LREM 和 LPUSH 把它们的条目移回队列,每次读取最多 128 个。

在集群上,两个列表必须散列到同一个槽,因为 BLMOVE 要访问两个键。两个键落在不同槽上的订阅拒绝启动。像 {jobs} 这样的哈希标签把两个键放到同一个槽上,默认的处理中键也随之落在这个槽。