7、Redis队列Stream和单线程及多线程模型
一、Redis Stream 消息队列
核心数据结构:Rax树(基数树)
核心特性:消息持久化、消费者组、消息回溯
1. 生产者操作
命令 | 示例 | 说明 |
---|---|---|
XADD | XADD mystream * name mark age 18 | 追加消息,* 自动生成ID(格式:<毫秒时间戳>-<序号> ) |
XDEL | XDEL mystream 1626705954593-0 | 逻辑删除(设置标志位) |
XRANGE | XRANGE mystream - + COUNT 2 | 查询消息(- 最小ID,+ 最大ID) |
XLEN | XLEN mystream | 获取消息数量(自动过滤已删除消息) |
2. 独立消费者模式
# 阻塞读取最新消息(0表示无限等待)
XREAD BLOCK 0 STREAMS mystream $
# 从指定ID开始读取
XREAD COUNT 2 STREAMS mystream 1626705954593-0
特点:无需消费者组,类似List的简单消费模式
3. 消费者组模式
# 创建消费者组
XGROUP CREATE mystream mygroup 0-0
# 消费者读取消息
XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >
关键机制:
last_delivered_id
:记录消费进度PEL
(Pending Entries List):已读取但未ACK的消息- 消息ACK:
XACK mystream mygroup 1626705954593-0
二、Redis线程模型演进
1. Redis 6.0前单线程模型
核心架构:单Reactor模式
特点:
- 纯内存操作,瓶颈在网络I/O而非CPU
- 异步线程处理:大Key删除、连接清理等
- 单线程QPS极限:约10万(Pipeline可达100万)
为何坚持单线程:
- 避免锁竞争、上下文切换开销
- 内存操作纳秒级完成,多线程收益有限
2. Redis 6.0多线程优化
配置参数:
io-threads 4 # 启用4个I/O线程(建议为核心数50-70%)
io-threads-do-reads yes # 开启读多线程
多线程流程:
线程分工
- 主线程:连接管理、命令执行、任务分配
- IO线程组:并行处理网络读写(read()/write()系统调用)
执行阶段
红色为单线程阶段
性能提升:
- 单机QPS提升至20万+
- 仅网络I/O多线程化,命令执行仍单线程(无并发安全问题)
三、关键对比与选型建议
特性 | Redis 5.0及以前 | Redis 6.0+ |
---|---|---|
线程模型 | 单线程Reactor | 多线程I/O + 单线程命令执行 |
适用场景 | 10万QPS以下业务 | 高并发热点访问(如热搜) |
配置复杂度 | 无需调优 | 需合理设置io-threads 参数 |
数据一致性 | 天然强一致 | 同左(命令执行仍单线程) |
四、生产环境最佳实践
-
Stream使用建议:
- 优先使用消费者组模式(支持ACK和故障恢复)
- 监控
PEL
队列积压:XPENDING mystream mygroup
-
线程模型调优:
# 监控多线程性能 redis-cli --stat # 查看线程状态 redis-cli info threads
- 建议值:
io-threads = CPU核心数×0.7
(如4核机器设为3)
- 建议值:
-
规避大Key问题:
# 异步删除大Key(非阻塞主线程) UNLINK big_stream
通过合理使用Stream和线程模型优化,Redis可支撑百万级消息队列和高并发访问。核心原则:I/O密集型场景启用多线程(如秒杀、热搜),CPU密集型操作保持单线程(如大量Lua脚本执行)。