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

Redis:线程模型

单线程模型

image _3_.png

Redis 自诞生以来,一直以高性能著称。很多人好奇,Redis 为什么早期采用单线程模型,它真的比多线程还快吗? 其实,Redis 的“快”并不在于并发线程,而在于其整体架构设计极致简单高效,主要体现在:

  1. 基于内存(最主要的原因),性能瓶颈不在 CPU:Redis 的数据全部存储在内存中,访问不涉及磁盘 I/O,CPU 在大多数情况下并不是瓶颈,因此不需要多线程分摊计算压力。

  2. 数据存取非常快

    • Redis 存储在内存中,读写速度接近极限;

    • 不需要频繁的上下文切换、内核态与用户态的转换;

    • 执行效率高,每个请求处理成本低。

  3. 避免多线程带来的复杂性

    • 单线程模型可以避免加锁、解锁、死锁等多线程并发问题

    • 无需线程上下文切换,节省 CPU 时间;

    • 更容易实现和维护。

  4. 多路复用机制:Redis 使用了基于事件驱动的 epoll(Linux)实现的I/O 多路复用模型,能够高效地处理大量客户端连接请求。

  5. 高效数据结构:非常适合内存操作的高效数据结构:SDS(简单动态字符串),ziplistlistpackquicklist跳表 skiplist; 这些结构可以保证极快的插入、查询、遍历效率。

引入多线程的原因

随着 Redis 用户量剧增、业务规模扩大,Redis 面临了一些新的挑战,也就是Redis的性能瓶颈:

网络 I/O,当连接数剧增(特别是高并发大请求的场景),网络数据的读取/写入成为瓶颈:

  • 虽然命令执行依然快速;

  • 但主线程需要花费大量时间在“读 socket、写 socket、解析协议”上。

为了解决网络瓶颈问题,Redis 从 6.0 开始引入 I/O 多线程机制

  • 仍然保留主线程执行命令的模型;
  • 引入多个后台 I/O 线程负责读写 socket 数据;
  • 实现真正意义上的读写分离、I/O 解耦

I/O 线程只做纯粹的网络数据传输,不涉及数据结构修改,不会产生线程安全问题,也不会破坏原有的单线程执行语义。

无法充分利用多核资源:多核时代,单线程只能用一个 CPU 核心,处理海量并发请求时能力不足。

三个核心后台线程

Redis 除了主线程之外,还有 3 个重要的后台线程,称为 BIO(Background I/O)线程,用于异步处理阻塞或耗时任务:

image.png

释放内存线程

  • 异步释放内存:Redis 执行删除、淘汰数据操作时,释放内存线程在后台异步释放内存,避免主线程卡顿,尤其处理大量数据删除时,能分散内存释放压力,保证系统并发处理能力。
  • 内存碎片整理:定期检查内存,整理碎片,合并不连续空闲内存块,提高内存利用率,降低内存分配失败概率,增强服务器稳定性。

AOF 刷盘线程

  • 日志重写:AOF 文件随时间和写操作增多会变大,AOF 重写线程在后台重写,依据数据库状态将键值对操作重记为命令,生成更小 AOF 文件,缩短服务器启动和数据恢复时间。
  • 数据一致性保证:重写时对数据库快照,记录开始状态,依据重写期间命令更新快照,合并更新后快照和命令记录成新 AOF 文件,确保数据一致性。

处理关闭文件线程

  • 大对象释放:删除或过期大对象时,Redis 将其放入待释放队列,由线程在后台逐步释放,避免主线程长时间阻塞,提升系统整体可用性。
  • 资源合理利用:根据系统负载和内存使用情况,合理安排大对象释放时间和频率,业务高峰期减慢释放,低谷期加快释放。
BIO 线程功能
AOF 刷盘线程everysec 策略下,每秒由后台线程执行 fsync 持久化
释放内存线程删除大 key 或触发过期淘汰时,为避免阻塞主线程,异步执行
处理关闭文件线程在 AOF 重写、RDB 持久化结束后,异步关闭文件描述符,释放资源

三个或多个 I/O 线程

Redis 在 6.0 之后支持配置若干个 I/O 线程,用于处理网络读取和写入

类型描述
读线程从客户端连接读取请求数据、解析协议
写线程将主线程处理完的响应结果写回客户端
默认配置默认只开启“写多线程”,读仍然由主线程处理

配置方式(redis.conf):

io-threads 4                 # 开启 4 个 I/O 线程(建议2-8之间)
io-threads-do-reads yes      # 启用读请求的多线程处理(默认关闭)

注意:即便开启多线程,命令解析和执行仍然是由 主线程 完成!

参考资料:小林coding

相关文章:

  • 小白学习java第12天:IO流之打印流、数据流、IO框架
  • Spark-core编程(三)
  • Redis与Caffeine的结合使用详解(高效的二级缓存解决方案)
  • 条件变量condition_variable
  • elementui table禁用全选,一次限制勾选一项。
  • vector的应用
  • Webpack中的文件指纹:给资源戴上个“名牌”
  • OpenCV 图形API(23)图像和通道合成
  • 组合模式计算多项式
  • 【MYSQL从入门到精通】数据库基础操作、数据类型
  • 数据结构 -- 图的遍历
  • 文件操作和IO - 2
  • Model Context Protocol(MCP)模型上下文协议
  • spark core编程之行动算子、累加器、广播变量
  • 在51单片机上实现平滑呼吸灯:50us定时器PWM实战指南
  • Shell脚本提交Spark任务简单案例
  • Java基础 4.12
  • 《jQuery EasyUI 插件》
  • Linux基础5
  • 【数据结构与算法】ArrayList 和 顺序表
  • 当当网电子商务网站建设特点/湖南seo优化价格
  • 微网站开发企业选择/做一个网站需要什么
  • 惠安网站建设/seo优化技术教程
  • 网站为什么上传不了图片/seo优化公司排名
  • 网站建设尺寸像素是多少/网络建站流程
  • 顺德做网站公司/四川聚顺成网络科技有限公司