Redis单线程为什么这么快?
第一章 Redis单线程为什么这么快
Redis深度剖析【第一章】
- Redis单线程为什么这么快?
- 前言
- 一、Redis为什么要使用单线程,而不是多线程?
- 单线程的优势
- 如果Redis使用多线程:
- 既然多线程切换存在消耗那么为什么JAVA和C#等编程语言又要使用多线程呢?
- 二、Redis快的原因
- Redis内部构造
- 1、网络事件处理器
- 2、文件处理器
- 三、Redis处理请求的流程
- 四、单线程快的原因
前言
在使用数据库是我们往往会使用reids来作为数据库前面的一道防护,由于reids的吞吐量更大所以一般都会用来作为缓存快速的响应,想必大家都或多或少听说过,或者使用过reids,如果你现在还只是知其然而不知其所以然,那么本篇文章将会给您带来帮助,让您看清reids内部的执行过程,让您知道它为什么是单线程却能那么快。
一、Redis为什么要使用单线程,而不是多线程?
单线程的优势
如果Redis使用多线程:
如下图,此时我们只有一个CPU有三个请求需要响应每个请求都需要处理两毫秒;CPU有自己的时间调度方法,可能它只分了1毫秒给线程1那么线程1接收到到这个请求后只处理了1毫秒还没处理完CPU就可能发生了切换切换到了线程3,而此时这个切换也会存在一个代价,因为线程1还没有处理完就直接切换到了线程3存在一个栈帧的一个切换,所以说CPU的切换时存在一定消耗的。
既然多线程切换存在消耗那么为什么JAVA和C#等编程语言又要使用多线程呢?
因为在JAVA和C#中线程的处理时间通常都会比较长,JAVA和C#往往会进行一些IO操作,或者是跟下游系统的一些交互,或者是操作一些文件,此时IO本身都会被阻塞,此时线程占用着CPU资源其实是没有什么实际用处的还不如切换出去,让其他的线程。此时的CPU切换其实本身效率还是比较高的。但是在Redis中它通常都不会操作IO,而是操作内存不需要阻塞等待如果发生CPU切换的话反而会降低性能
二、Redis快的原因
Redis内部构造
Redis是基于Reactor模式开发的网络事件处理器、文件事件处理器(file event handler)。文件事件处理器它是单线程的,所以我们才称Redis是单线程的模型。但是此时要注意我们所说的Redis是单线程模型并非指的是它只有一个线程,Redis它不是只有一个线程它后台也有很多后台线程。之所以说它是单线程的是因为它里面的网络事件处理器是单线程的。
1、网络事件处理器
网络事件处理器它采用了IO多路服用的一个机制,也就是说我们一个线程同时监听多个socket,根据Socket上的事件类型来选择对应事件处理器来处理这个事件。可以实现高性能的网络通信模型,有可以根据内部其他单线程的模块进行对接,保证了Redis内部线程模型的简单性
如下图:
Redis的socket监听到了来自socke1的信息会创建一个socket去处理他,如果此时socke2也发来信息,线程又会切换去socket2.
此时长得帅的小伙伴就要问了为什么能做到快速处理呢?
因为这些socket他们不是同时到来的。
那要是他们是同时来呢?
因为是单线程先来的socket会先处理只有等先来的socket处理完了才会处理后续到来的socket。
2、文件处理器
文件处理器的结构包括4个部分:多socket、IO多路复用程序、文件事件分派器、事件处理器(例如:命令请求处理器、命令回复处理器、链接应答处理器等)
多个socket可能并发的产生不同的事件,IO多路复用程序会监听多个socket,会将socket放入一个队列中排队,每次从队列中有序的、同步取出一个socket给事件分派器、事件分派器把socket给对应的事件处理器。然后一个socket的事件处理完之后,IO多路服用程序才会将队列中的下一个socket给事件分派器。文件事件分派器会根据每一个socket当前产生的事件,来选择对应的事件处理器进行处理。
三、Redis处理请求的流程
【AE_READABLET:读事件 | AE_WRITABLE:写事件 】
1、Redis,启动初始化时,将连接应答处理器跟AE_READABLET事件关联。
2、若一个客户端发起连接,会产生一个AE_READABLE事件,然后由连接应答处理器负责和客户端建立连接,创
建客户端对应的socket,同时将这个socket的AE_READABLE事件和命令请求处理器关联,使得客户端可以向主服
务器发送命令请求。
3、当客户端向Redis发请求时(不管读还是写请求),客户端socket都会产生一个AE_READABLE事件,触发命令
请求处理器。处理器读取客户端的命令内容,然后传给相关程序执行。
4、当Redis服务器准备好给客户端的响应数据后,会将socket的AE_WRITABLE事件和命令回复处理器关联,当客
户端准备好读取响应数据时,会在socketi产生一个AE_WRITABLE事件,由对应命令回复处理器处理,即将准备好
的响应数据写入socket,供客户端读取。
5、命令回复处理器全部写完到socket后,就会删除该socket的AE_VRITABLE事件和命令回复处理器的映射。
四、单线程快的原因
- 纯内存操作、不需要操作IO
- 核心是基于非阻塞IO多路复用机制
- 单线程反而避免了多线程的频繁上下文切换带来的性能问题