redis为什么可以支持高并发和它内部的工作模式有不可分割的关系:
- 绝大部分请求是纯粹的内存操作(非常快速)
- 采用单线程,避免了不必要的上下文切换和竞争条件
- 非阻塞IO - IO多路复用
Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有到达服务端的命令都不会立刻执行,所有的命令都会进入一个队列中,然后逐个执行,并且多个客户端发送的命令的执行顺序是不确定的,但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。
文件事件处理器结构包含5个部分,其实真正包含为4个部分(不包含socket队列,加上主要方便后面理解):多个socket、IO多路复用程序、socket队列、文件事件分派器、以及事件处理器。如图:
注:如果只是单纯的单线程,那么redis在每一次的IO处理上都会耗费很长的时间,但是redis这里使用了IO多路复用监听多个socket,哪个socket接收完成了请求的IO,就将这个scoket塞入socket队列,这样就大大减少了IO处理的时间。
如图可以看出
- 客户端请求过来,到了IO多路复用
- 监听到接收请求完成的socket,放入队列供文件事件分派器消费(这个过程是单线程的)
- 文件事件分派器在选择对应的事件处理器进行处理
这里只是简单解读了redis的内部工作模式,具体的多路复用原理大家需要了解可以自行了解。
但是这里得说明下redis这里主流程虽然是单线程,但并不代表redis任何时候都是单线程的,比如我们之前讲的redis持久化操作,就会启用一个子线程进行持久化操作,这种操作还存在很多场景,所以redis的单线程指的是redis的主流程单线程,既我们上述所讲的过程。
另外redis6.0好像也要引入上述主流程的多线程操作,因为在面试的时候被问到redis是单线程还是多线程时不能一口咬定就是单线程。