redis是一个事件驱动程序
- 他需要处理两类事件
- 文件事件
- 文件事件就是对套接字的抽象,服务器与客户端之间的通信会产生相应的时间事件,服务器通过监听这些事件完成网络操作
- 时间事件
- 时间事件就是一些操作需要在特定的时间完成
- 文件事件
文件事件
- redis通过reacter模式开发了自己的文件事件处理器
- 文件事件处理器通过IO多路复用程序来监听多个套接字,并为套接字绑定了多个事件处理程序
- 当一个套接字准备好accept,read,write,close等操作时,会产生相应的事件,这时事件处理程序就会调用相应的处理程序
- 使用IO多路复用模型,可以在实现高性能的网络响应模型的同时,保持了系统的简单性
文件事件处理器的构成
- 文件事件处理器包括套接字,IO多路复用处理程序,文件事件分派器,事件处理程序
- 文件事件其实是对套接字操作的抽象
- IO多路复用程序监听多个套接字,多个文件事件可能并发的出现,IO多路复用程序会将并发事件放在一个队列中,有序的同步的传递给文件事件处理程序
- 只有处理完一个文件事件之后,IO多路复用才会去处理下一个文件事件
- 文件事件分派器会将不同的文件事件分派给不同的文件时间处理程序
IO多路复用实现
redis使用的是c标准的select,poll,epoll等标准函数库,同时为这些库实现了相同的API,所以底层是可以互换的
文件事件的类型
文件事件分为AE_READABLE事件和AE_WRITABLE事件
- 当套接字可读时,即客户端准备对套接字进行write,或者有新的可应答套接字出现时,套接字产生AE_READABLE事件(write, close,accept)
- 当套接字变得可写时,客户端对套接字执行read操作,会产生AE_WRITEABLE事件(read)
- 同时IO多路复用还支持同时监听套接字两种事件,如果两种事件同时出现,优先处理AE_READABLE事件
文件事件处理器
redis为文件事件编写了多个处理器
- 为了对客户端进行应答,服务器为客户端关联链接应答处理器
- 为了接收客户端的命令请求,服务器为客户端关联命令请求处理器
- 为了向客户端返回命令结果,服务器要为客户端关联命令回复处理器
连接应答处理器
当系统刚初始化完成时,redis会将连接应答处理器和AE_READABLE事件关联起来
命令请求处理器
在客户端连接服务器的整个过程中,服务器会一直讲命令请求服务器和AE_READABLE事件关联起来
命令回复处理器
- 当服务器有命令结果需要返回给客户端时,会将命令回复处理器和AE_WRITEABLE事件绑定起来
- 当套接字变为可写时,会产生AE_WRITEABLE事件,命令回复处理器会将结果返回给客户端
- 之后,会接触命令回复处理器和AE_WRITEABLE事件的绑定
一次完整的客户端和服务器链接过程
时间事件
- 定时时间和周期型事件
- 一个时间事件有三个属相组成
- id,递增id,新事件比老的事件id大
- when,记录了事件的到达时间
- timeProc,时间事件处理函数
时间事件的实现
- 服务器将所有的时间事件都放在一个无需链表里,每当时间事件执行器运行时,就会便利这个链表
事件事件应用实例:serverCron函数
- redis中的事件事件任务都有serverCron函数负责执行,他的任务包括
- 更新服务器的各类统计信息,比如时间,内存占用,数据库占用等
- 清理数据库过期的键值对
- 关闭和清理链接失效的客户端
- 尝试进行RDB和AOF持久化操作
- 如果是主服务器则对从服务器定期同步
- 集群模式则对集群定期进行同步和连接测试
主循环处理文件事件和时间事件的伪代码
- 获取最接近的时间事件的还有多久到达
- 将该秒数传入IO监听函数,两个条件满足一个会向下执行
- 时间事件到达
- IO多路复用监听到文件事件产生
- 然后先执行文件事件
- 后执行时间事件
因为文件事件在时间事件之前执行,所以时间事件往往会比设定事件稍晚一点执行
重点回顾
- redis是一种事件驱动程序,处理的事件分为文件事件和时间事件两类
- redis的文件事件处理程序采用reacter模式
- 文件事件是对套接字操作的抽象:accept,read,write,close时,会产生文件事件
- 文件事件分为AE_READABLE和AE_WRITEABLE
- 时间事件分为定时事件和周期性事件
- redis一般情况下只执行serverCron一个时间事件,并且是周期性的
- 文件事件和时间事件是相互合作的关系,服务器会轮流处理这两类事件,相互不会枪战
- 事件事件一般会比设定的时间晚一点