Redis 事件机制
Redis 事件机制分为两种,一个文件事件、一个时间事件。
文件事件
文件事件分为读事件和写事件两类:读事件实现了命令请求的接收,写事件实现了命令结果的返回。
时间事件
时间事件分为单次执行事件和循环执行事件,服务器常规操作serverCron就是循环事件。
在 Redis 中, 常规操作由redis.c/serverCron
实现, 它主要执行以下操作:
- 更新服务器的各类统计信息,比如时间、内存占用、数据库占用情况等。
- 清理数据库中的过期键值对。
- 对不合理的数据库进行大小调整。
- 关闭和清理连接失效的客户端。
- 尝试进行 AOF 或 RDB 持久化操作。
- 如果服务器是主节点的话,对附属节点进行定期同步。
- 如果处于集群模式的话,对集群进行定期同步和连接测试。
事件调度
文件事件和时间事件之间是合作关系:一种事件会等待另一种事件完成之后再执行,不会出现抢占情况。
时间事件的实际执行时间通常会比预定时间晚一些。
对于像serverCron
这类循环执行的时间事件来说, 如果事件处理器的返回值是t
, 那么 Redis 只保证:
- 如果两次执行时间事件处理器之间的时间间隔大于等于
t
, 那么这个时间事件至少会被处理一次。 - 而并不是说, 每隔
t
时间, 就一定要执行一次事件 —— 这对于不使用抢占调度的 Redis 事件处理器来说,也是不可能做到的
例如,虽然serverCron
(sC
)设定的间隔为10
毫秒, 但它并不是像如下那样每隔10
毫秒就运行一次:
在实际中,serverCron
的运行方式更可能是这样子的:
time ----------------------------------------------------------------------->|
|<---- 10 ms ---->|<---- 10 ms ---->|<---- 10 ms ---->|<---- 10 ms ---->|
| FE 1 | FE 2 | sC 1 | FE 3 | FE 4 | FE 5 | sC 2 |
|<-------- 15 ms -------->| |<------- 12 ms ------->|
>= 10 ms >= 10 ms
^ ^ ^ ^
| | | |
file event time event | time event
handler handler | handler
run run | run
file event
handler
run
上图中的FE为文件事件的运行时间。根据情况, 如果处理文件事件耗费了非常多的时间,serverCron
被推迟到一两秒之后才能执行, 也是有可能的。