绍圣--kafka之服务端--时间轮

时间轮

Kafka中存在大量的延迟操作,比如延迟生产,延迟拉取,延迟加入,延迟心跳等。kafka使用时间轮(TimingWheel)来实现管理延迟任务和超时完成延迟任务。

时间轮(TimingWheel)是存储定时任务的环形队列,底层采用数组实现,数组中的每个元素可以存放一个定时任务列表(TimerTaskList)。定时任务列表(TimerTaskList)是一个双向链表,链表中的每一项都是一个定时任务项(TimerTaskEntry),定时任务项中封装的就是真的定时任务(TimerTaskEntry(比如延迟操作))。

时间轮由多个时间格(槽)组成,每个时间格(槽)代表当前时间轮的基本时间跨度(tickMs)。时间轮的时间格(槽)个数是固定的,通过wheelSize设置,时间轮的总体时间跨度interval=tickMs*wheelSize。表盘指针currentTime表示时间轮当前所处的时间,currentTime将整个时间轮划分为到期部分和未到期部分,currentTime当前指向的时间格属于到期部分,刚好到期,需要处理此时间格所对应的TimerTaskList的所有任务。

时间轮的tickMs=1ms,wheelSize=20,interval=20ms,初始情况下表盘指针currentTime指向时间格0,此时有一个延迟时间为2ms的任务进来,会存放到时间格为2的定时任务列表(TimerTaskList)中。随着时间不断的推移,currentTime不断向前推进,过了2ms之后,到达时间格2时,就需要将时间格2所对应的TimeTaskList中的任务做相应的到期操作。此时若又有一个延迟时间为8ms的任务插入进来,则会存放到时间格为10的任务列表(TimerTaskList)中,从中可以看出定时任务存放到哪个时间格中,是从当前表盘指针指向的时间格开始算起。不是从初始时间格开始算起。那么同时有一个延迟时间为19ms的任务,那么这个时候,这个任务就会存放到时间格为1中。

总结一下:只要延迟时间没有超过当前时间轮的跨度,都会存储在当前时间轮中,选择时间格从当前表盘指针指向的时间格的tickMs开始计算。这样随着表盘指针(currentTime)的不断推进,当前时间轮处理的时间段也在不断的后移,时间范围在currentTime于currentTime+interval之间。

当延迟时间超过了时间轮的跨度,如果是直接扩充当前时间轮的时间格(wheelSize的大小),那么在kafka的这种级别的延迟任务,那么这个时间轮会很大,比如100万毫秒,这种情况下时间轮就会占用很大的空间,并且走一轮的话,花费的时间也比较长。所以当延时时间超过了当前时间轮的跨度(interval),kafka会重新建立一个时间轮:第一个时间轮会持有第二个时间轮的引用,第一个时间轮的interval为第二个时间轮的tickMs。所以第二个时间轮:tickMs=20ms,wheelSize=20,interval=400ms。

这是来了一个延迟时间是350ms的延迟任务,第一层时间轮是不能满足的,于是只能想更高一层的时间轮来存储,第二层时间轮的跨度interval大于延迟时间,第二层可以满足存储这个延迟任务,所以这个350ms会被存到到第二层时间轮的17时间格中。时间格的超时时间是tickMs。但是时间格定时任务列表(TimerTaskList)中的延迟任务是一个链表,链表中的延迟任务的超时时间不全是tickMs,比如第二层时间轮的第17个时间格中就会存储延迟时间是340ms到360ms的延迟任务。所以当TimerTaskList超时之后,如果链表里面还有不能执行的延迟任务,就有一个时间轮的降级操作,比如第二层时间轮的第17个时间格在340ms到期后,里面这个360ms到期的任务还有20ms才能执行到期操作,这时第一层的时间轮可以存放这个还有20ms到期的延迟任务,所以这个延迟任务就修改自己延迟时间,并被再次加入到第一层的时间格中(这时如果第一层不能装下,就会往上层上放)。再过20ms后,真正到期,最终执行相应的到期操作。

怎么判断任务过期?

我们把时间轮的时间格(槽)放入到DelayQueue中,因为每个时间格(槽)都有统一的一个过期时间,这个过期的槽会被DelayQueue的poll弹出,我们只需要将槽中的所有任务循环一次,重新加入到新的槽中,添加失败就立即执行。

参考:

原 荐 简单说说Kafka中的时间轮算法-腾讯云资讯

Kafka解惑之时间轮(TimingWheel) - 朱小厮的博客 - CSDN博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 服务端在处理客户端的请求,针对不同的请求,可能不会立即返回响应结果给客户端。在处理这类请求时,服务端会为这类请求创...
    绍圣阅读 9,094评论 0 0
  • 在kafka中,有许多请求并不是立即返回,而且处理完一些异步操作或者等待某些条件达成后才返回,这些请求一般都会带有...
    疯狂的哈丘阅读 29,176评论 3 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,601评论 18 139
  • 零、时间轮定义 简单说说时间轮吧,它是一个高效的延时队列,或者说定时器。实际上现在网上对于时间轮算法的解释很多,定...
    Java大生阅读 1,947评论 1 0
  • 本想翻一翻从前的故事,却看到了曾经写下的这篇文章。本不想分享,可还是敲了下来。或许是因为太久没有写关于这方面的文了...
    苏瑾微读阅读 245评论 4 2