Redis Stream消息队列
Redis 的五种数据结构各有特色,用对了才能发挥它的优势。很多人只用到了 String 和 Hash,却不知道 List、Set、ZSet 在特定场景下更合适。本文从应用场景出发,讲什么时候用什么类型。
一、Stream基础
#
1.1 什么是Stream
Stream是Redis的日志型数据结构:
┌─────────────────────────────────────────────────────────────┐ |
#
1.2 Stream ID格式
Stream ID: <millisecondsTime>-<sequenceNumber> |
二、Stream命令
#
2.1 添加消息
# XADD stream_name [MAXLEN len] [ID id] field value [field value ...] |
#
2.2 读取消息
# XRANGE: 按范围读取 |
#
2.3 删除消息
# XDEL: 删除指定消息 |
#
2.4 获取Stream信息
# XLEN: 获取消息数量 |
三、消费者组
#
3.1 消费者组概念
┌─────────────────────────────────────────┐ |
#
3.2 消费者组命令
# XGROUP CREATE: 创建消费者组 |
四、Java中使用Stream
#
4.1 Spring Data Redis
|
#
4.2 生产者实现
|
#
4.3 消费者实现
|
#
4.4 Spring Boot Stream Listener
|
五、Stream vs List作为消息队列
| 特性 | Stream | List |
|---|---|---|
| 消息持久化 | 是 | 是 |
| 消息ID | 自动生成时间戳ID | 无(需自己维护) |
| 消费者组 | 原生支持 | 不支持 |
| 消息确认 | 支持ACK | 不支持 |
| 消息回溯 | 支持 | 不支持(pop后删除) |
| 消息数量 | 可查询 | 可查询 |
| 消息内容 | 支持多字段 | 单个String |
| 阻塞读取 | 支持 | 支持(BLPOP) |
| 适用场景 | 复杂消息队列 | 简单队列 |
六、最佳实践
#
6.1 消息清理
# 设置Stream最大长度(自动清理旧消息) |
#
6.2 异常处理
|
#
6.3 监控
# 查看Stream长度 |
七、总结
| 场景 | 推荐方案 |
|---|---|
| 简单队列 | List + BLPOP |
| 复杂消息队列 | Stream + 消费者组 |
| 需要ACK确认 | Stream |
| 需要消息回溯 | Stream |
| 日志收集 | Stream |
| 事件驱动架构 | Stream + 多消费者组 |
Stream的核心价值:
- 消息持久化:不丢失消息
- 消费者组:负载均衡和广播
- 消息确认:可靠消费
- 消息回溯:可重新消费历史消息
使用建议:
- 使用MAXLEN控制Stream大小
- 及时处理pending消息
- 合理设置消费者组数量
- 监控Stream长度和消费者延迟
核心要点
String:简单的键值对,适合缓存、计数器
Hash:存储对象属性,适合用户信息、配置
List:有序列表,适合消息队列、最新列表
Set:无序去重,适合共同好友、抽奖
ZSet:有序集合,适合排行榜、积分系统
总结
选择合适的数据结构是使用 Redis 的关键。在实际项目中,根据业务需求选择合适的类型,可以提升性能和开发效率。