Redis的单线程模型与多线程优化

单线程模型

redis是单线程模型,在处理客户端请求时,使用单线程结合多路复用技术 来执行网络 I/O 和命令处理,6.0后引入多线程来优化处理网络IO

了让单进程的服务端应用同时处理多个客户端的事件,Redis 采用了 IO 多路复用机制。

这里"多路"指的是多个网络连接客户端,"复用"指的是复用同一个线程来监听多个Socket的连接状态。

  1. 多个客户端与服务端连接时, I/O 多路复用程序 会将客户端 socket 对应的 FD 套接字 注册到监听列表(一个队列)中

  2. 当客户端执行readwrite等操作命令时,多路复用程序会将命令封装成一个事件,并绑定到对应的事件处理器上进行处理。

  3. 事件分发器通过 epoll 函数 监控多个文件描述符(fd)的读写情况,当 accept、read、write 和 close 文件事件产生时,就会回调 FD 绑定的事件处理器进行处理相关命令操作。

具体事件处理过程就是,主线程会就进入到一个事件循环函数,主要会做以下事情:

  • 首先,先调用处理发送队列函数 ,看是发送队列里是否有任务,如果有发送任务,则通过 write 函数将客户端发送缓存区里的数据发送出去,如果这一轮数据没有发送完,就会注册写事件处理函数,等待epoll_wait发现可写后再处理

  • 然后调用 epoll_wait函数等待事件的到来

    • 如果是连接事件 到来,则会调用连接事件处理函数 ,调用accpet获取已连接的 socket -> 将已连接的 socket 加入到 epoll -> 注册「读事件」处理函数;

    • 如果是读事件 到来,则会调用读事件处理函数,调用 read 获取客户端发送的数据 -> 解析命令 -> 处理命令 -> 将客户端对象添加到发送队列 -> 将执行结果写到发送缓存区等待发送;

    • 如果是写事件 到来,则会调用写事件处理函数,通过 write 函数将客户端发送缓存区里的数据发送出去,如果这一轮数据没有发送完,就会继续注册写事件处理函数,等待 epoll_wait 发现可写后再处理 。

为什么这么快?

主要有3个方面的原因,分别是存储方式、优秀的线程型以及 I/O 模型、高效的数据结构。

  • Redis 将数据存储在内存中,提供快速的读写速度,相比于传统的磁盘数据库,内存访问速度快得多。

  • Redis 使用单线程结合I/O多路复用,避免了多线程上下文切换和竞争条件,提高了并发处理效率。

  • Redis 提供多种高效的数据结构(如字符串、哈希、列表、集合等),这些结构经过优化,能够快速完成各种操作

6.0 版本为何引入多线程?

因为单线程编程容易并且更容易维护。其次Redis 的性能瓶颈不在 CPU,主要在内存和网络

多线程可能会存在死锁、线程上下文切换等问题,甚至会影响性能

Redis 6.0 对于网络 I/O 采用多线程来处理,而命令的解析与执行仍然保持单线程模式。这样既保留了单线程执行的简洁性和安全性,又提高了网络I/O的吞吐量。

Redis 6.0 版本支持的 I/O 多线程特性,默认情况下 I/O 多线程只针对发送响应数据,并不会以多线程的方式处理用户读请求

  • 阶段一: 主线程负责接收并创建与客户端的连接,并通过轮询将这些连接分配给I/O线程。

  • 阶段二 : 默认配置下,I/O线程不参与从客户端读取命令请求的过程。即默认情况下,主线程负责从Socket读取客户端请求并解析命令。但是,如果配置了io-threads-do-reads yes,那么I/O线程也会参与到读请求的处理中

  • 阶段三: 无论是否使用多线程进行读取,命令的执行都是由主线程完成的,以保证命令执行顺序和避免复杂的并发问题。

  • 阶段四: 在命令执行完毕后,结果会被放入缓冲区。然后,I/O线程负责将这些结果写回到客户端,从而加快响应速度。

开启多线程后,还需要设置线程数,否则是不生效的。

复制代码
同样需要修改redis 配置文件redis.conf  io-threads 4 #官网建议4核的机器建议设置为2或3个线程,8核的建议设置为6个线程
相关推荐
卡布奇诺-海晨11 分钟前
MySQL的MVCC机制
数据库·mysql
hao_wujing38 分钟前
攻击模型的恶意行为检测
网络·数据库·php
秃头摸鱼侠2 小时前
MySQL查询语句(续)
数据库·mysql
MuYiLuck2 小时前
【redis实战篇】第八天
数据库·redis·缓存
睡觉待开机2 小时前
6. MySQL基本查询
数据库·mysql
�FENG2 小时前
Redis 安装配置和性能优化
redis·持久化
大熊猫侯佩2 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(三)
数据库·swiftui·swift
大熊猫侯佩2 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(二)
数据库·swiftui·swift
大熊猫侯佩3 小时前
用异步序列优雅的监听 SwiftData 2.0 中历史追踪记录(History Trace)的变化
数据库·swiftui·swift
大熊猫侯佩3 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(一)
数据库·swiftui·swift