redis pub/sub 不支持优先级处理,因其是无状态、无缓冲、不持久的广播机制;真正可行的方案是用 list + brpop 多键轮询实现硬性优先级,并通过 pub/sub 作为轻量通知层触发拉取。

Redis Pub/Sub 本身不支持优先级处理,任何尝试在 PUBLISH 或 SUBSCRIBE 层面实现优先级的做法都是无效的。 它是纯广播、无缓冲、无顺序、不持久的瞬时通道,消息发出去就没了,订阅者收到即处理,没收到就丢弃——根本不存在“排队”或“插队”的概念。
为什么不能直接用 Pub/Sub 做优先级队列
常见错误现象包括:
- 用
PUBLISH task:high '{"id":1}'后让 worker 直接消费该消息 → 消息可能因 worker 离线而永久丢失 - 以为订阅多个频道(如
SUBSCRIBE high medium low)就能按顺序响应 → 实际上所有频道消息并发到达,无先后保障 - 试图用
psubscribe task:*+ 消息体里带 priority 字段来区分 → 订阅者仍需自行过滤、排序、延迟处理,失去实时性且易出错
根本原因:Pub/Sub 没有服务端状态,不保存消息,不控制消费节奏,也不提供原子性弹出机制。它只负责「喊一嗓子」,不是「交任务」。
真正可行的优先级方案:List + BRPOP 多键轮询
把不同优先级任务写入不同 key,靠 BRPOP 的左优先弹出特性实现硬性优先级:
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 高优任务用
LPUSH queue:high ...写入 - 中优任务用
LPUSH queue:medium ...写入 - 低优任务用
LPUSH queue:low ...写入 - 消费者执行
BRPOP queue:high queue:medium queue:low 0,永远先查queue:high,空了才往下走
BRPOP 是原子操作:即使 queue:high 在检查瞬间为空,下一个指令也绝不会跳到 queue:medium 而漏掉刚进来的高优任务。这是 Redis 底层保证的,无需加锁。
如何让 Pub/Sub 和优先级队列协同工作
Pub/Sub 可以作为轻量通知层,触发对 List 的主动拉取,避免长轮询浪费资源:
- 生产者做完
LPUSH queue:high ...后,立刻PUBLISH notify:high "ready" - 监听
notify:high的 worker 收到信号后,立即执行一次BRPOP queue:high queue:medium queue:low 0 - 注意:
SUBSCRIBE notify:high收到的只是字符串"ready",不是任务内容;真实载荷始终在 List 里
多个 worker 共用同一组优先级队列完全安全:BRPOP 天然支持并发竞争,Redis 保证每次只有一个 client 成功弹出元素。但要警惕:如果 queue:high 持续积压,queue:low 可能长期得不到处理——这不是缺陷,是优先级设计的必然结果,需要配套监控 LLEN queue:low 并设置告警阈值。










