前言

在读这篇文章之前需要意识到redis线程安全,是IO多路复用+单线程处理命令工作的,redis是事件驱动程序。

redis一个命令请求过程

一、建立连接

IO多路复用技术

1、redis服务器采用IO多路复用技术,那么到底什么是IO多路复用技术,这里以netty举例,使用一个Boss线程处理accept,建立连接。建立连接后,把连接绑定给一个Work线程处理,work线程不断做select系统调用轮询,如果有read事件,利用分排器,分派文件事件。有人可能说了,redis不是单线程吗,那来的这么多线程。这里需要说明,多路复用技术是妥妥的多线程,redis 单线程的意思也不是它完全单线程。

2、Io多路复用如何保证消息顺序。对于一个客户端与服务器建立的单个tcp连接,io多路复用保证,只有一个work线程能够处理,这样TCP本身就保证有序性+单个线程处理一个socket的所有请求。保证了消息的顺序。

redis多线程 io顺序 redis怎么实现多线程_多线程

redis连接池

1、redis连接池,redis客户端也采用了连接池化的技术。为什么redis采用池化技术,就是因为,网络io的速度远慢于redis服务器处理命令的速度。所以需要多个socket连接去并发访问redis服务器,redis服务器又支持Io多路复用技术,可以通过多个线程分派多个socket的命令。

2、客户端使用了redis连接池,还能保证请求命令的顺序吗?显然是不能的。那么问题来了

redis多线程 io顺序 redis怎么实现多线程_文件事件_02


像这样两行代码,难道第二行的代码可能会比第一行代码产生的redis命令先执行吗,当然是不可能的,redis客户端是同步执行的,第一行代码执行,没有收到redis服务器的执行成功或者失败回复会一直阻塞。

二、发送命令

接受命令并分派文件事件

1、当IO多路复用机制通过轮询发现了accept,read,write事件之后。就会调用先关联的处理器进行处理
2、例如,IO多路复用程序发现有read事件,触发read事件关联的文件事件进行处理

文件事件

1、什么是文件事件

redis多线程 io顺序 redis怎么实现多线程_redis多线程 io顺序_03


2、文件事件如何保证线程安全

redis多线程 io顺序 redis怎么实现多线程_redis多线程 io顺序_04


这里说明了,文件事件可能同时有很多个,但是都会被放入到队列中,由redis的单线程去消费队列里的事件。是由单线程执行的,因此是线程安全的。

3、文件事件如何处理命令

redis多线程 io顺序 redis怎么实现多线程_文件事件_05


1)按照redis的协议从命令请求,并保存到相应客户端的缓冲区中

2) 对请求进行解析,提取出命令以及命令参数,例如

redis多线程 io顺序 redis怎么实现多线程_redis_06


3)调用命令执行器,执行指定的命令调用对应命令的函数,被调用函数处理请求并产生响应的回复,对客户端的回复会被写入输出缓冲区中。最后由回复处理器将命令返回给客户端。

redis多线程 io顺序 redis怎么实现多线程_多线程_07

每次写命令后都会被写到aof缓冲区,至于何时刷到磁盘,由配置决定。

三、redis定时任务

时间事件

redis启动后,就使用单线程一直在不断的执行文件事件和时间事件,文件事件由io触发,时间事件由redis本身设置延时时间执行或者周期执行。

redis多线程 io顺序 redis怎么实现多线程_文件事件_08

时间事件实例:serverCron函数

redis多线程 io顺序 redis怎么实现多线程_redis多线程 io顺序_09

时间事件和文件事件怎么由一个单线程执行

redis多线程 io顺序 redis怎么实现多线程_多路复用_10


由此可以看出,文件事件和时间事件都是同步,有序,原子执行的,因此redis 的过期任务,在redis运行期间删除数据也不会导致线程安全问题。