定时器是 redis 异步处理事件的一个十分重要的功能。redis 定时器功能由多个时间事件组成,事件由一个双向链表维护。时间事件可以处理多个定时任务。
理解 redis 定时器,我们带着问题,看看 redis 是怎么处理的:
- 定时器作用是什么。
- 定时器实现原理。
- 单进程里如何同时处理文件事件和时间事件。
- 如何实现多定时任务。
🔥文章来源:wenfh2020.com
1. 作用
定时器是 redis 异步处理任务的一个十分重要的功能。核心逻辑在 serverCron 函数里。
- 对设置了过期时间的数据进行检查回收。
- 异步回收需要关闭的链接(socket)。
- 检查 fork 的子进程是否已经关闭,处理回收的相关工作。
- 检查内存数据是否符合 rdb 持久化快照落地条件,fork 子进程进行快照保存。
bgsaverdb 生成快照或bgrewriteaofaof 重写延后操作。- 对需要扩容和缩容的哈希表(dict)进行数据迁移。
- 集群里节点间的断线重连。
- redis 服务的一些信息统计。
- …等等。
2. 定时器实现原理
redis 定时器功能由多个时间事件组成,事件由一个双向链表维护。有些实现逻辑,上文已经提到,下面就简单说一下部分实现原理。
2.1. 事件结构
- 事件。
// 时间事件
typedef struct aeTimeEvent {
long long id; /* time event identifier. */
long when_sec; /* seconds */
long when_ms; /* milliseconds */
aeTimeProc *timeProc; /* 时钟到期事件触发回调处理函数。*/
aeEventFinalizerProc *finalizerProc; /* 时间事件删除时,触发回调。*/
void *clientData; /* 扩展参数,异步操作方便数据回调,在 timeProc 通过参数回传。*/
struct aeTimeEvent *prev; /* 时间事件是一个双向链表。*/
struct aeTimeEvent *next;
} aeTimeEvent;
// 事件管理
typedef struct aeEventLoop {
...
long long timeEventNextId; // 时间事件下一个 id (通过 ‘++’ 递增)
...
aeTimeEvent *timeEventHead; // 时间事件链表。
...
} aeEventLoop;
- 事件循环。
// 循环处理事件。
void aeMain(aeEventLoop *eventLoop) {
eventLoop->stop = 0;
while (!eventLoop->stop) {
if (eventLoop->beforesleep != NULL)
eventLoop->beforesleep(eventLoop);
aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
}
}
- 事件回调函数。
// 时间事件触发处理函数。
typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);
// 时间事件处理完毕,被删除时,触发的回调处理。
typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);
- 创建时间事件,时间事件通过双向链表管理,新的事件插入到链表头。
long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
aeTimeProc *proc, void *clientData,
aeEventFinalizerProc *finalizerProc) {
// 事件 id 递增。
long long id = eventLoop->timeEventNextId++;
aeTimeEvent *te;
te = zmalloc(sizeof(*te));
if (te == NULL)

本文详细探讨了Redis定时器的功能及其实现原理,包括定时器的作用、实现机制、单进程异步事件处理逻辑、多定时任务处理以及定时器执行频率控制。通过分析,读者将了解到Redis如何高效管理时间事件,处理过期数据回收、持久化快照、链接回收等关键任务。
最低0.47元/天 解锁文章
1274

被折叠的 条评论
为什么被折叠?



