redis服务器是一个事件驱动的程序,服务器需要处理以下两类事件
- 文件事件:比如服务器与客户之间的命令就是通过socket,一个命令对应一个事件
- 时间事件:比如serverCron函数
文件事件(file event)
- 文件事件一般都是网络事件,redis基于reactor模式开发了一套文件事件处理器(整个过程类似netty比如单独的线程去处理事件的接受,单独的线程去处理事件,在集群模式下就是一个节点接收到一个请求看看该key是否在自己的管辖范围 不是的话则返回moved给客户端里面包含正确的地址,然后客户端重新定位到正确的地址)
-
文件事件处理器使用了IO多路复用,文件事件处理器内部图如下:
image.png
- 中间io多路复用到文件事件分派器使用的是队列
- 多路复用的实现包含 select epoll evport 和kqueue,在不同的系统中采用不同的方式
AE_READBLE事件对应着socket可读(里面包含客户端对socket执行了write或者close 或者有新的可连接socket)。类似于客户端对服务端的操作
AE_WRITEABLE(当客户端对socket执行read操作时候)。 类似服务端响应客户端
- 上述两者事件同时发生时候,优先处理readble在处理writeable
不同的事件对应不同的处理器
-
连接应答处理器:服务端为监听的socket关联一个该处理器,用来客户端连接要求
image.png
- 命令请求处理器:为了接受客户端传递来的命令请求,服务端要为客户端的socket关联该处理器

- 命令回复处理器: 为了向客户端返回执行结果

- 复制处理器: 当主从服务器进行复制操作,主从服务器都需要复制处理器
整个处理过程如下
image.png
时间事件 (time event)
事件时间可以分为定时和周期
-
时间事件主要由三个属性组成:id,when,timeProc
id:服务器为事件创立的全局唯一ID,ID号按照从小到大顺序递增
when: 毫秒精度的unix时间戳,记录了时间事件的到达时间(即何时开始执行)
timeProc:时间事件处理器,当事件到达时候如何处理 -
一个事件是定时还是周期性事件取决于时间事件处理器的返回值
-
如果返回AE_NOMORE 那么就是定时事件,该事件在达到之后就删除
-
如果返回的是是非AE_NOMORE那么就是周期性事件,该事件在达到之后 服务器会对时间事件的when属性进行更新,让其隔一段时间之后再次到达
实现
- redis采用无序(指的是when的无序,而不是id的无序)链表保存时间事件,每当时间事件运行,他就遍历整个链表,查找所有已到达的时间事件,并调用相应的事件处理器
- 采用了头插法,每次新的时间事件都插入在头部
-
正是因为没有按照when排序 所以每次都需要遍历
image.png
image.png
serverCron函数主要做的事情
image.png
如何处理文件和时间事件,以及他们各自耗时多久来处理(类似于netty的处理io和task)
- 主要是由aeProcessEvents函数负责
- 整个流程就是获取快要到达的时间的时间事件,然后在根据这个快要到达的时间去获取文件事件,然后依次处理文件和时间事件


当我们将上述aeProcessEvents放入循环里面 在加上初始化和清理函数,这就sredis服务器的主函数


网友评论