对Redis是单线程的理解

前言

当面试官问你Redis是单线程还是多线程?你肯定会说:单线程!然后他就会问:单线程为啥还这么快?你就会说出这几条原因:

1、Redis是基于内存的,内存的读写速度非常快,从内存中拿数据比从磁盘上更快。

2、Redis是基于I/O多路复用(非阻塞IO),可以摆脱多线程上下文切换消耗的影响,

你如果真这么说 那她可能也许大概不会太满意

个人理解

redis分客户端和服务端,一次完整的redis请求事件有多个阶段:

1、客户端到服务器的网络连接

2、redis读写事件发生

3、redis服务端的数据处理(单线程)

4、将处理后的数据返回

平时所说的redis单线程模型,本质上指的是服务端的数据处理阶段,不牵扯网络连接,这是理解redis单线程的第一步。接下来,针对不同阶段分别阐述个人的一些理解。

1、客户端到服务器的网络连接
首先,客户端和服务器是socket通信方式,socket服务端监听可同时接受多个客户端请求。

扫描二维码关注公众号,回复: 13136117 查看本文章

假设建立网络连接需要30秒(假设!其实时间非常短)

2、redis读写事件发生并向服务端发送请求数据
首先确定一点,redis的客户端与服务器端通信是基于TCP连接,三次握手后才能保证双方可靠,第一阶段仅仅是建立了客户端到服务器的网络连接,然后才是发生第二阶段的读写事件。

完成了上一个阶段的网络连接,redis客户端开始真正向服务器发起读写事件,假设是set(写)事件,此时redis客户端开始向建立的网络流中送数据,服务端可以理解为给每一个网络连接创建一个线程同时接收客户端的请求数据。

假设从客户端发数据,到服务端接收完数据需要10秒。

3、redis服务端的数据处理
服务端完成了第二阶段的数据接收,接下来开始依据接收到的数据做逻辑处理,然后得到处理后的数据。数据处理可以理解为一次方法调用,带参调用方法,最终得到方法返回值。

假设redis服务端处理数据需要0.1秒

4、将处理后的数据返回
这一阶段很简单,当reids服务端数据处理完后 就会立即返回处理后的数据。

假设服务端把处理后的数据回送给客户端需要5秒。

那么什么是Reids的单线程

第一阶段说过,redis是以socket方式通信,socket服务端可同时接受多个客户端请求连接,也就是说,redis服务同时面对多个redis客户端连接请求,而redis服务本身是单线程运行。

假设,现在有A,B,C,D,E五个客户端同时发起redis请求,A优先稍微一点点第一个到达,然后是B,C,D,E依次到达,此时redis服务端开始处理A请求,建立连接需要30秒,获取请求数据需要10秒,然后处理数据需要0.1秒,回送数据给客户端需要5秒,总共大概需要45秒。也就是说,下一个B请求需要等待45秒,这里注意,也许这五个几乎同时请求,由于socket可以同时处理多个请求,所以建立网络连接阶段时间差可忽略,但是在第二阶段,服务端需要什么事都不干,坐等10秒中,对于CPU和客户端来说是无法忍受的。所以说单线程效率非常,非常低,但是正是因为这些类似问题,Redis单线程本质上并不是如此运行。接下来讨论redis真正的单线程运行方式。

客户端与服务端建立连接交由socket,可以同时建立多个连接(这里应该是多线程/多进程),建立的连接redis是知道的,然后redis会基于这些建立的连接去探测哪个连接已经接收完了客户端的请求数据(注意:不是探测哪个连接建立好了,而是探测哪个接收完了请求数据),而且这里的探测动作就是单线程的开始,一旦探测到则基于接收到的数据开始数据处理阶段,然后返回数据,再继续探测下一个已经接收完请求数据的网络连接。注意,从探测到数据处理再到数据返回,全程单线程。这应该就是所谓的redis单线程。至于内部有多复杂我们无需关心,我们追求的是理解流程,苛求原理,但不能把内脏都挖出来。

从探测到接受完请求数据的网络连接到最终的数据返回,服务器只需要5.1秒,这个时间是我放大N倍后的数据,实际时间远远小于这个,可能是5.1的N万分之一时间,为什么这么说,因为数据的处理是在本地内存中,速度有多快任你想象,最终的返回数据虽然牵扯到网络,但是网络连接已经建立,这个速度也是非常非常快的,只是比数据处理阶段慢那么一点点。因此单线程方式在效率上其实并不需要担心。

转载自知乎:https://zhuanlan.zhihu.com/p/128598311

猜你喜欢

转载自blog.csdn.net/DDDDeng_/article/details/107758214