当前位置: 首页 > news >正文

7、Redis队列Stream和单线程及多线程模型

一、Redis Stream 消息队列

核心数据结构:Rax树(基数树)
核心特性:消息持久化、消费者组、消息回溯

1. 生产者操作
命令示例说明
XADDXADD mystream * name mark age 18追加消息,*自动生成ID(格式:<毫秒时间戳>-<序号>
XDELXDEL mystream 1626705954593-0逻辑删除(设置标志位)
XRANGEXRANGE mystream - + COUNT 2查询消息(-最小ID,+最大ID)
XLENXLEN 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模式

处理
处理
处理
单线程Reactor
IO多路复用器
epoll/kqueue
客户端请求
文件事件分派器
命令请求处理器
命令回复处理器
连接应答处理器
单线程执行
SET/GET等命令
异步线程
大Key删除
连接清理
脏数据回收

特点

  • 纯内存操作,瓶颈在网络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线程组
读取
写入
读取
写入
Socket数据
IO线程1
响应数据
IO线程2
Socket数据
响应数据
Socket存入等待队列
接收新连接
轮询分配Socket
给IO线程组
阻塞等待IO线程
完成读写
单线程执行命令
将响应写入队列
通知IO线程回写
客户端1
客户端1
客户端2
客户端2

线程分工

  • 主线程:连接管理、命令执行、任务分配
  • IO线程组:并行处理网络读写(read()/write()系统调用)

执行阶段
红色为单线程阶段

网络读
命令解析
内存操作
响应编码
网络写

性能提升

  • 单机QPS提升至20万+
  • 仅网络I/O多线程化,命令执行仍单线程(无并发安全问题)

三、关键对比与选型建议
特性Redis 5.0及以前Redis 6.0+
线程模型单线程Reactor多线程I/O + 单线程命令执行
适用场景10万QPS以下业务高并发热点访问(如热搜)
配置复杂度无需调优需合理设置io-threads参数
数据一致性天然强一致同左(命令执行仍单线程)

四、生产环境最佳实践
  1. Stream使用建议

    • 优先使用消费者组模式(支持ACK和故障恢复)
    • 监控PEL队列积压:XPENDING mystream mygroup
  2. 线程模型调优

    # 监控多线程性能
    redis-cli --stat
    # 查看线程状态
    redis-cli info threads
    
    • 建议值:io-threads = CPU核心数×0.7(如4核机器设为3)
  3. 规避大Key问题

    # 异步删除大Key(非阻塞主线程)
    UNLINK big_stream
    

通过合理使用Stream和线程模型优化,Redis可支撑百万级消息队列和高并发访问。核心原则:I/O密集型场景启用多线程(如秒杀、热搜),CPU密集型操作保持单线程(如大量Lua脚本执行)

http://www.lryc.cn/news/610933.html

相关文章:

  • 人工智能领域、图欧科技、IMYAI智能助手2025年4月更新月报
  • 【RK3576】【Android14】Uboot下fastboot命令支持
  • 创维智能融合终端DT741_移动版_S905L3芯片_安卓9_线刷固件包
  • CTF-XXE 漏洞解题思路总结
  • 测试开发:Python+Django实现接口测试工具
  • Python-初学openCV——图像预处理(七)——亮度变换、形态学变换
  • ThingsKit Edge是什么?
  • 从零实现富文本编辑器#6-浏览器选区与编辑器选区模型同步
  • 数据结构 | 树的秘密
  • 在Linux上部署tomcat、nginx
  • CRT调试堆检测:从原理到实战的资源泄漏排查指南
  • Apifox使用mock模仿后端返回数据
  • JumpServer 堡垒机全流程搭建指南及常见问题解决方案
  • Redis存储string里面embstr和raw格式区别
  • 【Linux】特效爆满的Vim的配置方法 and make/Makefile原理
  • 【01】OpenCV C++实战篇——基于多项式插值的亚像素边缘定位算法
  • Occ3D: A Large-Scale 3D Occupancy Prediction Benchmark for Autonomous Driving
  • Python爬虫实战:研究weiboSpider技术,构建新浪微博数据采集系统
  • 多层Model更新多层ListView
  • RHCA05--进程管理与文件系统管理
  • 数据结构(01)—— 数据结构的基本概念
  • 应用科普 | 漫谈6G通信的未来
  • 【技术教程】如何将 ONLYOFFICE 文档连接到 Confluence
  • 坚鹏:AI智能体软件是知行学成为AI智能体创新应用引领者的抓手
  • Fiddler 中文版实战指南,如何构建高效的 API 调试工作流?
  • Z20K118库中寄存器及其库函数封装-ADC库
  • Linux操作系统从入门到实战(十三)版本控制器Git基础概念讲解
  • 自抗扰ADCR--跟踪微分器的作用
  • sqli-labs通关笔记-第32关 GET宽字符注入(单引号闭合 手工注入+脚本注入两种方法)
  • Android 中几种常用布局的优缺点