Administrator
Published on 2026-03-13 / 5 Visits
0

Redis ZSet 做延迟队列

#AI

一、结论

Redis ZSet 完全可以做延迟队列
原理:用 score 存到期时间戳,按时间排序,轮询取已到期任务。


二、核心原理(极简)

  • ZSet 是有序集合,按 score 从小到大排序
  • 任务 ID 作为 value
  • 延迟执行时间戳作为 score
  • 消费者轮询:取 score ≤ 当前时间的任务

三、完整流程(生产可用)

1. 生产(加入延迟任务)

ZADD delay_queue 执行时间戳 task_id

例:5秒后执行

ZADD delay_queue ${now+5000} order_12345

2. 消费(取出到期任务)

循环执行两步:

  1. 查最早到期的任务
ZRANGEBYSCORE delay_queue 0 ${now} LIMIT 0 1
  1. 尝试删除(原子性,防重复消费)
ZREM delay_queue task_id
  • 返回 1 → 抢到任务,执行
  • 返回 0 → 被其他消费者拿走,跳过

四、优点

  • 实现极简单,不用额外中间件
  • 支持百万级延迟任务
  • 支持分布式多消费者
  • 可随时查看/删除/修改延迟任务
  • 基于 Redis,运维成本低

五、缺点(必须知道)

  • 需要轮询,空转有轻微 CPU/IO 消耗
  • 没有内置 ack 机制,丢任务需自己做(如移到 pending 队列)
  • 不支持严格消息可靠性(Redis 宕机可能丢消息)
  • 高并发大规模场景不如 RabbitMQ、RocketMQ、Pulsar

六、适合/不适合

✅ 适合

  • 订单超时未支付取消
  • 未审核自动过期
  • 验证码超时失效
  • 中小型项目、简单业务

❌ 不适合

  • 金融级强可靠消息
  • 百万级 TPS 延迟队列
  • 必须零丢失、零重复

七、对比:ZSet vs 专门 MQ

方案复杂度可靠性性能
Redis ZSet极低一般
RabbitMQ 死信
RocketMQ 延迟消息中高很高很高

一句话总结

小项目、简单延迟需求 → 用 Redis ZSet 最快最好;
高可靠、大规模 → 用专业 MQ。