1、 时间轮介绍
image.jpeg内部结构
时间轮可以理解为一种环形结构,像钟表一样被分为多个 slot 槽位。每个 slot 代表一个时间段,每个 slot 中可以存放多个任务,使用的是链表结构保存该时间段到期的所有任务。时间轮通过一个时针随着时间一个个 slot 转动,并执行 slot 中的所有到期任务。
时间轮内部结构其实是 HashedWheelBucket 数组,每个 HashedWheelBucket 表示时间轮中一个 slot。从 HashedWheelBucket 的结构定义可以看出,HashedWheelBucket 内部是一个双向链表结构,双向链表的每个节点持有一个 HashedWheelTimeout 对象,HashedWheelTimeout 代表一个定时任务。每个 HashedWheelBucket 都包含双向链表 head 和 tail 两个 HashedWheelTimeout 节点,这样就可以实现不同方向进行链表遍历
image.jpeg任务添加
当任务添加过程,可以根据任务的到期时间进行取模,然后将任务分布到不同的 slot 中。如上图所示,时间轮被划分为 8 个 slot,每个 slot 代表 1s,当前时针指向 2。假如现在需要调度一个 3s 后执行的任务,应该加入 2+3=5 的 slot 中;如果需要调度一个 12s 以后的任务,需要等待时针完整走完一圈 round 零 4 个 slot,需要放入第 (2+12)%8=6 个 slot。
当需要把 round 信息保存在任务中。例如图中第 6 个 slot 的链表中包含 3 个任务,第一个任务 round=0,需要立即执行;第二个任务 round=1,需要等待 18=8s 后执行;第三个任务 round=2,需要等待 28=8s 后执行。所以当时针转动到对应 slot 时,只执行 round=0 的任务,slot 中其余任务的 round 应当减 1,等待下一个 round 之后执行。
如果多个任务如果对应同一个 slot,处理冲突的方法采用的是拉链法。在任务数量比较多的场景下,适当增加时间轮的 slot 数量,可以减少时针转动时遍历的任务个数。
时间轮定时器最大的优势就是,任务的新增和取消都是 O(1) 时间复杂度,而且只需要一个线程就可以驱动时间轮进行工作。
任务处理
整个核心任务处理代码是一个 do-while 循环
1、 首先计算出时针到下一次 tick 的时间间隔,然后 sleep 到下一次 tick。
2、通过取模运算获取当前 tick 在 HashedWheelBucket 数组中对应的下标,同时移除被取消的任务。
3、从 Queue 中取出任务加入对应的 HashedWheelBucket 中。
4、 执行当前 HashedWheelBucket 中的到期任务。
3、 自定义延时消息实现方案
image.jpegRocketMQ 自定义延迟消息二开实现
Broker 端存储
- 首先将业务topic转化为系统topic并将消息append到message_log中,然后再通过回放message_log构造schedule_index日志。schedule_index则有offsetId+size+schedule_time 构成
- 预加载 schedule_index,通过配置可以设置提前多久将加载schedule_index到内存中,默认1小时。 预加载过程其实在启动的时候启动一个 ScheduledExecutorService,默认1min进行扫描检测一次。
- 加载 主要将延迟消息的MessageId、延时时间、偏移量都加载到时间轮里。即两层HashWheel。第一层位于磁盘上,例如,以一个小时一个刻度一个文件,我们叫delay_message_segment,如延迟时间为2021年04月07日 19:00 至2021年04月07日 20:00为延迟消息将被存储在2021040719。并且这个刻度是可以配置调整的。第二层HashWheel位于内存中。也是以一个时间为刻度,比如1s,加载进内存中的延迟消息文件会根据延迟时间hash到一个HashWheel中。
Broker 端投递转化
- 时间轮中通过定时器进行每秒轮转,针对到期的延时消息转投到Message_log中,主要包括 通过时间轮上的MessageId 查询 原先的Message_log并将查到的Message_log转化到业务topic的Message_log中,最终被消费端快速消费。
- 由于时间轮基于内存,当机器宕机或者重启需要将延时消息重新加载。
5.1.时间轮读取当前一个小时内的 schedule_index
5.2. 对于已经过当前时间的消息,发送前还需检测 dispatch_log 是否已投递,没有则立即重新发送,否则不发送。
网友评论