1、多路复用
多路”指的是多个网络链接,“复用”指的是复用同一个线程redis

多路I/O复用模型是利用 select、poll、epoll 能够同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,因而程序就会轮询一遍全部的流(epoll 是只轮询那些真正发出了事件的流),而且只依次顺序的处理就绪的流,这种作法就避免了大量的无用操做数据库
redis使用多路复用技术,能够处理并发的链接。非阻塞IO 内部实现采用epoll,采用了epoll+本身实现的简单的事件框架。epoll中的读、写、关闭、链接都转化成了事件,而后利用epoll的多路复用特性,毫不在io上浪费一点时间服务器
2、Redis事件
Redis服务器是一个事件驱动程序,主要处理如下两类事件:网络
- 文件事件:文件事件其实就是对Socket操做的抽象,Redis服务器与Redis客户端的通讯会产生文件事件,服务器经过监听并处理这些事件来完成一系列的网络操做
- 时间事件:时间事件其实就是对定时操做的抽象,前面咱们已经讲了RDB、AOF、定时删除键这些操做均可以由服务端去定时或者周期去完成,底层就是经过触发时间事件来实现的
2.1 文件事件并发
文件事件是对套接字操做的抽象, 每当一个套接字准备好执行链接应答(accept)、写入、读取、关闭等操做时, 就会产生一个文件事件。 由于一个服务器一般会链接多个套接字, 因此多个文件事件有可能会并发地出现框架
Redis 基于 Reactor 模式开发了本身的事件处理器函数

尽管多个文件事件可能会并发地出现, 但 I/O 多路复用程序老是会将全部产生事件的套接字都入队到一个队列里面, 而后经过这个队列, 以有序(sequentially)、同步(synchronously)、每次一个套接字的方式向文件事件分派器传送套接字: 当上一个套接字产生的事件被处理完毕以后(该套接字为事件所关联的事件处理器执行完毕), I/O 多路复用程序才会继续向文件事件分派器传送下一个套接字.spa
Redis 客户端与服务器进行链接并发送命令的整个过程线程

- Redis 客户端向服务器发起链接
- 监听套接字将产生
AE_READABLE
事件, 触发链接应答处理器执行: 处理器会对客户端的链接请求进行应答, 而后建立客户端套接字, 以及客户端状态, 并将客户端套接字的AE_READABLE
事件与命令请求处理器进行关联, 使得客户端能够向主服务器发送命令请求 - 客户端向主服务器发送一个命令请求, 那么客户端套接字将产生
AE_READABLE
事件,发命令请求处理器执行, 处理器读取客户端的命令内容, 而后传给相关程序去执行 - 执行命令将产生相应的命令回复, 为了将这些命令回复传送回客户端, 服务器会将客户端套接字的
AE_WRITABLE
事件与命令回复处理器进行关联: 当客户端尝试读取命令回复的时候, 客户端套接字将产生AE_WRITABLE
事件, 触发命令回复处理器执行, 当命令回复处理器将命令回复所有写入到套接字以后, 服务器就会解除客户端套接字的AE_WRITABLE
事件与命令回复处理器之间的关联
2.2 时间事件code
持续运行的Redis服务器会按期对自身的资源和状态进行检查和调整,这些按期的操做由serverCron函数负责执行,它的主要工做包括:
- 更新服务器的统计信息(时间、内存占用、数据库占用)
- 清理数据库的过时键值对
- AOF、RDB持久化
- 若是是主从服务器,对从服务器进行按期同步
- 若是是集群模式,对进群进行按期同步和链接
Redis服务器将时间事件放在一个链表中,当时间事件执行器运行时,会遍历整个链表。时间事件包括:
- 周期性事件(Redis通常只执行serverCron时间事件,serverCron时间事件是周期性的)
- 定时事件
执行思路:
- 记录最新一次执行这个函数的时间,用于处理系统时间被修改产生的问题。
- 遍历链表找出全部 when_sec 和 when_ms 小于如今时间的事件。
- 执行事件对应的处理函数。
- 检查事件类型,若是是周期事件则刷新该事件下一次的执行事件。
- 不然从列表中删除事件