Redis中的Stream详解
Redis 中的 Stream 详解
Redis 在 5.0 引入了 Stream 数据结构,用于解决传统数据结构(如 List、Pub/Sub)在消息队列场景中的不足。
Stream 可以看作是一个:
支持持久化、可回溯、带消费组的日志型消息队列
它的设计目标是提供类似 Kafka 的核心能力,但更轻量、更易用。
目录
- Redis 中的 Stream 详解
一、Stream 是什么
从本质上看,Stream 是一种:
按时间顺序追加的消息日志(append-only log)
你可以类比:
| 概念 | 类比 |
|---|---|
| Stream | Kafka Topic |
| Entry(消息) | 一条日志 |
| Consumer Group | 消费组 |
| Consumer | 消费者 |

二、Stream 的数据结构
一个 Stream 由多个 Entry(消息)组成:
1 | mystream |
2.1 消息 ID 结构
每条消息都有唯一 ID:
1 | timestamp-sequence |
例如:
1 | 1700000000000-0 |
含义:
- timestamp:毫秒时间戳
- sequence:同一毫秒内的递增序号
👉 特点:
- 全局有序
- 可用于定位消费位置
三、基本操作
3.1 写入消息
1 | XADD mystream * key value |
说明:
*表示自动生成 ID
3.2 读取消息
1 | XREAD STREAMS mystream 0 |
3.3 阻塞读取
1 | XREAD BLOCK 5000 STREAMS mystream $ |
$:从最新消息开始- BLOCK:阻塞等待新消息
四、消费组机制
Stream 最核心能力之一是消费组。
4.1 创建消费组
1 | XGROUP CREATE mystream group1 0 |
4.2 消费消息
1 | XREADGROUP GROUP group1 consumer1 STREAMS mystream > |
说明:
>:只消费新消息- 自动分配给不同消费者
4.3 负载均衡
多个消费者:
1 | group1 |
👉 Redis 会自动分配消息,实现负载均衡
五、消息读取模型:Pull 还是 Push?
5.1 核心结论
Redis Stream 是 拉取模型(Pull)
5.2 两种方式
非阻塞轮询
1 | XREAD STREAMS mystream 0 |
阻塞读取(推荐)
1 | XREAD BLOCK 5000 STREAMS mystream $ |
5.3 工作原理
1 | 消费者发起请求 |
👉 本质:
阻塞等待 + 事件唤醒(不是推送)
六、可靠性:为什么能做到至少一次消费
6.1 三大机制
- Consumer Group
- Pending List(未确认队列)
- ACK 确认机制
6.2 消息生命周期
1 | XADD 写入 |
6.3 Pending List 的作用
记录:
所有“已投递但未确认”的消息
6.4 宕机恢复
查看未确认消息
1 | XPENDING mystream group1 |
重新分配
1 | XCLAIM mystream group1 consumer2 60000 <id> |
6.5 为什么不会丢消息
- 未 ACK 不删除
- 可以重新分配
6.6 为什么会重复消费
1 | 处理成功 |
👉 因此是:
At-Least-Once(至少一次)
七、Stream vs List vs Pub/Sub
| 特性 | List | Pub/Sub | Stream |
|---|---|---|---|
| 持久化 | ❌ | ❌ | ✔ |
| 消费组 | ❌ | ❌ | ✔ |
| ACK | ❌ | ❌ | ✔ |
| 可回溯 | ❌ | ❌ | ✔ |
| 可靠性 | 低 | 低 | 高 |
八、底层实现原理
Stream 并不是简单链表,而是:
- Radix Tree(基数树)
-
- listpack(压缩结构)
8.1 优势
- 内存占用低
- 支持海量数据
- 按 ID 有序存储
九、使用场景
9.1 异步任务队列
- 订单处理
- 邮件发送
9.2 日志流处理
- 用户行为
- 系统日志
9.3 轻量级消息队列
- 替代 RabbitMQ(简单场景)
- 小规模替代 Kafka
十、面试高频总结
10.1 Stream 是什么?
日志型消息队列,支持消费组和可靠消费
10.2 如何感知新消息?
阻塞拉取(BLOCK)+ 事件唤醒
10.3 如何保证可靠性?
Pending List + ACK + 重分配
10.4 为什么是至少一次?
ACK 可能失败 → 重复消费
十一、总结
Redis Stream 是一个基于拉取模型的持久化消息队列,通过消费组、Pending List 和 ACK 机制,实现可回溯和至少一次的可靠消费。