Redis服务器处理两大类事件,时间事件和文件事件。(本次的笔记写的有点像填空题,,,
文件事件
通过对套接字的操作,完成对客户端请求的相应,监听套接字使用I/O多路复用程序,并为套接字关联不同的事件处理器。
I/O多路复用程序通过队列向文件事件分派器传送套接字,因此,尽管文件事件可能并发出现,套接字的传送依然是有序、同步的。
I/O多路复用可参考Linux IO模式,select、poll、epoll。
文件事件分为AE_READABLE(读事件)和AE_WRITABLE(写事件),当套接字变得可读,或有新的可应答(客户端对服务器监听的套接字建立连接时),套接字产生读事件,当套接字变得可写时,套接字产生写事件。
当一个套接字同时产生读事件和写事件时,服务器将先处理读事件,再处理写事件。
文件事件的处理器大致有以下几类,连接应答处理器、命令请求处理器、命令回复处理器及主从服务器复制时的复制处理器,其中,前三类较为常用。
时间事件
时间事件分为定时事件和周期性事件两类。定时事件只出现一次,周期性事件周期性出现。目前版本的Redis只使用周期性事件,没有定时事件。
在一般情况下,服务器只执行serverCon函数一个时间事件,并且该事件是周期性事件,默认每100ms执行一次,它的主要工作包括:
- 更新服务器的各类统计信息,比如时间、内存占用、数据库占用情况等。
- 清理数据库中的过期键值对。
- 关闭和清理连接失效的客户端。
- 尝试进行AOF或RDB持久化操作。
- 如果服务器是主服务器,那么对从服务器进行定期同步。
- 如果处于集群模式,对集群进行定期同步和连接测试。
事件调度与处理
事件调度主要分为以下4个步骤:
- 计算最接近的时间事件距离到达还有多少毫秒。
- 根据获得的毫秒数,阻塞并等待文件事件的产生。
- 处理所有产生的文件事件。
- 处理所有到达的时间事件。
特点
- 阻塞事件由到达时间最接近的时间事件确定,既可以避免忙等待,又不会阻塞太长时间。
- 文件事件与时间事件的处理都是同步、有序、原子地执行,服务器不会中断事件处理,也不会对事件抢占,因此,事件处理器会尽可能减少阻塞时间。例如,命令回复处理器将回复写入客户端套接字时,如果字节数超过了某个预设常量,处理器就会主动跳出循环,将剩余数据留到下次再写;时间事件也会将非常耗时的持久化操作放到子线程或子进程执行。
- 时间事件在文件事件之后执行,因此实际处理事件通常比到达事件稍晚些。