ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

redis的线程模型

redis的线程模型 Redis 的线程模型其实是分两块的Redis 6.0 之前的单线程模型。其实从 4.0 开始Redis 并不是严格意义上的单线程模型因为 Redis 除了主线程外也有一些后台的线程或者子进程在处理任务例如清理脏数据、生成快照、AOF 重写这个时候大家所说的单线程应该是 Redis 的主线程模型。Redis 6.0 之后的多线程模型。Redis 在 6.0 之后引入了一种多线程模型用于处理网络 I/O 的任务。所以你的回答要涉及这两个方面。Redis 的单线程是指Redis 在执行一次命令时是单线程的。其过程包括接收客户端请求 - 解析请求 -数据读写等操作-返回结果给客户端这个过程是由一个主线程来完成的这也是我们常说 Redis 是单线程的原因。Redis 的模型是基于单线程事件驱动模型内部使用文件事件处理器而这个文件事件处理是单线程的也就决定了 Redis 是单线程的。其核心原理是采用 IO多路复用机制同时监听多个 socket将产生事件的 socket 压入内存队列中事件分派器根据 socket 上的事件类型来选择对应的事件处理器进行处理。随着底层网络硬件越来越好Redis 的性能瓶颈逐渐体现在网络 I/O 的读写上单个线程处理网络 I/O 读写的速度跟不上底层网络硬件执行的速度。所以为了提高 Redis 的性能在 Redis 6.0 引入多线程模型该多线程模型只用来处理网络数据的读写和协议解析执行读写命令的仍然是单线程。Redis 线程模型详解Redis 的单线程模型Redis 的单线程是指Redis 在执行一次命令时是单线程的。Redis 客户端与服务端的模型可以简化如下图步骤2 执行命令为单线程其过程包括「接收客户端请求 - 解析请求 -数据读写等操作-返回结果给客户端」这个过程是由一个主线程来完成的这也是我们常说 Redis 是单线程的原因。从 Redis 的内部设计来说Redis 是基于 Reactor 模式开发了自己的网络事件处理器这个处理器称之为文件事件处理器而这个文件事件处理器是单线程的这就决定了 Redis 是单线程的。文件事件处理器包含 5 个部分多个 socketRedis 网络通信的起点Redis 服务器为每个连接的客户端维护一个套接字用于接收请求和发送响应。IO 多路复用程序文件事件处理器的核心。它负责监控所有套接字并确定哪些套接字准备好进行读写操作。任务队列处理的任务的队列。文件事件分派器当 I/O 多路复用程序确定某个套接字准备好读写时文件事件分派器负责将这个事件分派给相应的事件处理器。事件处理器Redis 对不同类型的文件事件定义了相应的事件处理器。当特定类型的事件发生时对应的事件处理器会被触发以处理这些事件。多个 socket 会产生不同的操作每个操作对应一个不同的文件事件 IO 多路复用程序会监听多个 socket将产生的事件放入到任务队列中排队文件事件分派器每次从任务队列中获取一个事件将其转发给对应的事件处理器进行处理。如下客户端与 Redis 服务端建立连接的过程Redis sever 启动时会把 AE_READABLE 事件与连接应答处理器关联。当客户端向 Redis 发起连接时这是 Server Socket 会产生一个 AE_READABLE 事件IO 多路复用程序监听到该事件后将 socket信息压入到任务队列中。文件事件分派器每次从任务队列中取一个 socket 将其交给事件处理器由于在 Redis 初始化时 AE_READABLE 是与连接应答处理器关联所以就由连接应答处理器来处理该事件。连接应答处理器会创建一个与该客户端通信的 Socket我们这里叫 socket1并将 socket1 的 AE_READABLE 事件与命令请求处理器关联。客户端发送请求给 Redis 服务端过程客户端发送读写请求比如 set key value给服务端首先会在对应的 Socketsocket1上面产生一个 AE_READABLE事件IO 多路复用程序监听到该事件后将 socket信息压入到任务队列中。文件事件分派器从任务队列中取 Socket 信息转发给事件处理器由于建立连接时 socket1 的 AE_READABLE 事件已经与命令请求处理器关联了所以文件事件分派器将命令请求处理器。命令处理器读取该 Socket 的相关信息后执行相关命令操作完成后会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联。如果客户端已经准备好了接收结果那么 socket1 会产生一个 AE_WRITABLEIO 多路复用程序将 Socket 压入队列然后由文件事件派发器转发给事件处理器。由于 socket1 的AE_WRITABLE 事件与命令回复处理器关联所以由命令回复处理器处理命令回复处理器将准备好的相应数据写入socket01(socket连接是双向的)返回给客户端之后解除 socket01 的 AE_WRITABLE 事件与命令回复处理器的关联。Redis 的 I/O 多线程模型我们 Redis 是基于内存操作内存的响应时长大约为 100 纳秒单线程的 Redis 处理数据的极限是 80,000 到 100,000 QPS对于绝大多数的场景来说单线程的 Redis 其实是已经够用了。但是随着底层网络硬件越来越好Redis 的性能瓶颈逐渐体现在 I/O 的读写上CPU 从来都不是 Redis 的性能瓶颈单个线程处理网络 I/O 读写的速度跟不上底层网络硬件执行的速度。所以为了提高 Redis 的整体性能在 6.0 引入多线程注意引入的多线程模型只⽤来处理处理网络数据的读写和协议解析对于 Redis 的读写命令依然是单线程处理。Redis 6.0 引入 I/O 多线程模型后将一个命令的执行分为了两部分Socket 读写和请求解析使用多线程处理多个 socket 读写可以并行化执行请求依然还是使用主线程存内存操作在高效的同时也保证了安全性。主要流程如下主线程负责接收并建立多个连接请求获取 socket 后放入全局等待处理队列主线程处理完这些事件之后通过RRRound Robin 轮询将可读 socket 分配给这些 IO 线程主线程阻塞等待 IO 线程完成命令的读取、解析主线程执⾏ IO 线程读取和解析出来的 Redis 请求命令并将结果写到输出缓冲区主线程阻塞等待 IO 线程将命令执⾏结果写回 socket客户端主线程执行所有命令并清空整个等待队列等待客户端后续的请求队列。如下图什么是IO多路复用I/O 指的是网络 I/O 多路指的是多个 TCP 连接如 Socket复用指的是复用一个或多个线程。I/O 多路复用的核心原理就是不再由应用程序自己来监听连接而是由服务器内核替应用程序监听。Redis IO多路复用是Redis一种高性能、高效的IO模型用于处理多个客户端与Redis服务器之间的通信。通过使用IO多路复用Redis可以在单个线程中同时处理多个客户端请求而不需要为每个客户端请求创建一个线程或进程。在传统的IO模型中每个客户端请求都需要在一个独立的线程中处理这样会导致系统资源的浪费并且在高并发的情况下会产生大量的线程切换开销。而使用IO多路复用的方式Redis只需要一个线程来监听所有的客户端连接当有客户端请求到达时通过IO多路复用机制可以有效地管理和响应多个请求。Redis IO多路复用的底层是利用操作系统的相关机制来实现的不同的操作系统有不同的实现方式常用的有select、poll和epoll等。这些机制使得Redis可以同时监听多个客户端的连接并在有数据到达时立即做出响应提高了系统的响应能力和吞吐量。在使用IO多路复用的模型中Redis通过将客户端的套接字文件描述符socket注册到一个事件监听器中当有事件发生时如读取或写入数据则将对应的回调函数放入事件处理器中执行。这样可以实现多个客户端之间的并发处理提高系统的整体性能和效率。Redis 中 I/O 多路复用的应用Redis 服务器是一个事件驱动程序服务器需要处理两类事件文件事件和时间事件。文件事件Redis 服务器和客户端或其他服务器进行通信会产生相应的文件事件然后服务器通过监听并处理这些事件来完成一系列的通信操作。时间事件Redis 内部的一些在给定时间之内需要进行的操作。Redis 的文件事件处理器以单线程的方式运行其内部使用了 I/O 多路复用程序来同时监听多个套接字Socket连接提升了性能的同时又保持了内部单线程设计的简单性。下图就是文件事件处理器的示意图I/O 多路复用程序虽然会同时监听多个Socket连接但是其会将监听的Socket都放到一个队列里面然后通过这个队列有序的同步的将每个Socket对应的事件传送给文件事件分派器再由文件事件分派器分派给对应的事件处理器进行处理只有当一个Socket所对应的事件被处理完毕之后I/O多路复用程序才会继续向文件事件分派器传送下一个Socket所对应的事件这也可以验证上面的结论处理客户端的命令请求是单线程的方式逐个处理但是事件处理器内并不是只有一个线程。世界上凡是具有奋斗精神的民族都生生不息富足和快乐。世界上凡是具有奋斗精神的企业都基业常青受人尊敬。中华民族是这样的民族华为和一大批中国的优秀企业是这样的企业。这样的民族和企业没有理由不赢得自己应得的地位不自立于世界民族之林。任正非要快乐地度过充满困难的一生部分内容引用自https://zhuanlan.zhihu.com/p/691176452deepseek总结Redis 的线程模型经历了演变分两个版本讲Redis 6.0 之前单线程模型Redis 6.0 之后多线程 I/O
返回列表