2. Redis 作为消息队列:List、Pub/Sub、Stream 三种模式对比与选型

在异步任务与事件驱动架构中,Redis 提供了三种截然不同的消息传递模式:List、Pub/Sub 和 Stream。它们各自适用于不同的场景,选型错误会导致消息丢失、消费延迟或系统复杂度失控。本章从数据结构、消息可靠性、消费模型、适用场景四个维度进行深度对比。

2.1 三种模式核心原理

2.1.1 List 模式(阻塞队列)

基于 Redis 的 List 数据结构,通过 LPUSH 入队、BRPOP 阻塞出队实现生产者-消费者模型。消息被消费后即从队列中删除,天然支持至少一次语义。

关键命令:
# 生产者
LPUSH task_queue task_data

# 消费者(阻塞等待,超时 0 表示无限等待)
BRPOP task_queue 0

2.1.2 Pub/Sub 模式(发布/订阅)

基于频道(Channel)的广播模型。生产者向频道发布消息,所有订阅该频道的消费者实时接收。消息不持久化,消费者离线则丢失消息。

典型场景:实时通知、心跳检测、日志广播。不适合需要可靠投递的任务队列。

2.1.3 Stream 模式(消息日志)

Redis 5.0 引入的日志型数据结构。每条消息有唯一 ID,支持消费者组(Consumer Group)、消息确认(ACK)、消息回溯。兼顾了 List 的可靠性和 Pub/Sub 的广播能力。

关键命令:
# 生产者
XADD mystream * field1 value1 field2 value2

# 消费者组创建
XGROUP CREATE mystream mygroup $

# 消费者读取
XREADGROUP GROUP mygroup consumer1 COUNT 1 BLOCK 0 STREAMS mystream >
Redis 三种消息模式架构对比 List 模式 生产者 生产者 List 队列(LPUSH/BRPOP) 消息消费即删除 消费者 A 消费者 B 特点:消息可靠,消费即删 不支持广播,不支持回溯 Pub/Sub 模式 发布者 发布者 频道(Channel) 消息不持久化 订阅者 A 订阅者 B 特点:实时广播,低延迟 离线丢失,不支持回溯 Stream 模式 生产者 生产者 Stream 日志(XADD) 消息持久化,可回溯 消费者组 A 消费者组 B 特点:可靠持久,支持组消费 支持 ACK 和消息回溯

2.2 核心维度对比

对比维度 List Pub/Sub Stream
消息持久化 是(RDB/AOF) 否 是(RDB/AOF)
消息可靠性 至少一次(消费即删) 最多一次(离线丢失) 至少一次(ACK 确认)
消费模型 竞争消费 广播消费 竞争 + 广播(消费者组)
消息回溯 不支持 不支持 支持(按 ID 范围)
阻塞读取 BRPOP/BLPOP SUBSCRIBE XREADGROUP BLOCK
消息确认 无(消费即确认) 无 XACK 显式确认
消费者组 无 无 有(XGROUP)
消息积压处理 队列长度增长 丢弃 日志追加,可限流
适用版本 所有版本 所有版本 Redis 5.0+

2.3 选型决策树

根据业务需求,按以下优先级进行选型:

  1. 是否需要消息持久化? 否 → Pub/Sub;是 → 进入下一步。
  2. 是否需要消息回溯/重放? 是 → Stream;否 → 进入下一步。
  3. 是否需要消费者组(负载均衡)? 是 → Stream;否 → 进入下一步。
  4. 是否需要广播消费? 是 → Stream(多消费者组);否 → List。
避坑提示:不要用 Pub/Sub 做任务队列。Pub/Sub 不持久化消息,消费者离线或网络抖动会导致消息永久丢失。如果任务队列需要“至少一次”语义,请使用 List 或 Stream。
Redis 消息队列选型决策流程 开始选型 需要消息持久化? (重启不丢失) 否 Pub/Sub 实时广播 离线丢失 是 需要消息回溯/重放? (消费失败后重试) 是 Stream 持久化 + 回溯 消费者组支持 否 需要消费者组(负载均衡)? (多消费者协同消费) 是 Stream 消费者组 + ACK 否 List 简单可靠队列 消费即删

2.4 场景推荐速查

业务场景 推荐模式 理由
异步任务队列(邮件、短信) List 或 Stream 需要持久化,至少一次语义
实时聊天/通知推送 Pub/Sub 低延迟广播,允许少量丢失
事件溯源/审计日志 Stream 需要消息回溯和持久化
多消费者负载均衡 Stream 原生消费者组支持
简单 FIFO 队列 List 实现简单,性能高
系统心跳/状态广播 Pub/Sub 无需持久化,实时性要求高

2.5 性能与可靠性权衡

  • List 模式:性能最高(单线程 O(1) 操作),但缺乏消息确认机制。消费者崩溃会导致消息丢失。适合对可靠性要求不高的内部任务队列。
  • Pub/Sub 模式:延迟最低(微秒级),但消息不持久化。消费者必须在线才能接收。适合实时监控、日志流等场景。
  • Stream 模式:功能最全,但性能略低于 List(需要维护消息 ID 和消费者组状态)。适合需要可靠投递、消息回溯、多消费者协同的复杂场景。
性能基准参考(单节点 Redis,消息体 1KB):
List:约 100,000 ops/s(LPUSH + BRPOP)
Pub/Sub:约 80,000 ops/s(PUBLISH + SUBSCRIBE)
Stream:约 50,000 ops/s(XADD + XREADGROUP)
实际性能受网络、消息大小、消费者数量影响。

2.6 总结

三种模式各有适用边界:

  • List:简单可靠,适合轻量级任务队列。
  • Pub/Sub:实时广播,适合通知类场景。
  • Stream:全功能消息系统,适合企业级异步任务。

在异步任务领域,Stream 是首选,因为它同时提供了持久化、消费者组、消息确认和回溯能力。List 可作为轻量替代,Pub/Sub 仅用于非关键实时通道。