Redis服务器是一个事件驱动程序,有两类事件需要处理:
- 文件事件:网络客户端通过socket与服务器进行通信。
- 时间事件:服务器定时任务的执行。
1. 事件循环
1 | typedef struct aeEventLoop { |
Redis通过事件循环处理,实现了与客户端的交互和定时任务。
2. 文件事件
Redis的文件事件处理基于Reactor模式。
2.1 定义
1 | typedef struct aeFileEvent { |
服务器通过多路IO复用库来监听客户端的多个套接字,并根据不同的事件类型关联不同的处理函数,当事件就绪时,调用相应的处理函数。
2.2 I/O多路复用库
Redis中I/O多路复用由evport,kqueue,epoll和select实现,它们的性能从高到低依次排列。
- evport:Solaris 10 的新增加的特性,高效的事件处理库。
- kqueue: FreeBSD系列的库。
- epoll:Linux 2.6增加的特性。
- select:通用的事件处理库。
3. 时间事件
3.1 定义
1 | typedef struct aeTimeEvent { |
Redis中,时间事件全部存储在一个无序链表timeEventHead中,每当时间事件执行时,服务器就遍历整个链表,查找所有已到达事件,并进行处理。
3.2 serverCron函数
Redis服务器需要定期对自身进行数据处理和状态检查,从而确保服务稳定运行。要执行的任务有:
- 定期检查使用情况,进行rehash操作
- 清理过期键
- 关闭和清理无效客户端
- AOF和RDB持久化
- 集群模式,主从数据同步
4. 源码剖析
- 初始化事件循环处理器
1 | aeEventLoop *aeCreateEventLoop(int setsize) { |
- 事件处理程序
1 | /* Process every pending time event, then every pending file event |
- 执行时间事件
1 | static int processTimeEvents(aeEventLoop *eventLoop) { |