Kafka如何实现延迟队列

参考答案

Kafka 并没有使用 JDK 自带的 Timer 、或者 DelayQueue 来实现延迟的功能,而是基于时间轮,自定义了一个用于实现延迟功能的定时器(SystemTimer)

  • JDK的 Timer 和 DelayQueue 插入和删除操作的平均时间复杂度为O(nlog(n)),并不能满足Kafka的高性能要求,而基于时间轮可以将插入和删除操作的时间复杂度都降为O(1)。
  • 时间轮的应用并非Kafka独有,其应用场景还有很多,在Netty、Akka、Quartz、Zookeeper等组件中都存在时间轮的踪影。
  • 底层使用数组实现,数组中的每个元素可以存放一个TimerTaskList对象。TimerTaskList是一个环形双向链表,在其中的链表项TimerTaskEntry 中封装了真正的定时任务TimerTask。

Kafka 中的定时器,借助了JDK中的DelayQueue来协助推进时间轮。具体做法:

  • 对每个使用到的TimerTaskList,都会加入到DelayQueue中。
  • Kafka中的TimingWheel专门用来执行插入和删除TimerTaskEntry的操作,而DelayQueue专门负责时间推进的任务。
  • 再试想一下,DelayQueue中的第一个超时任务列表的expiration为200ms,第二个超时任务为840ms,这里获取DelayQueue的队头只需要O(1)的时间复杂度。
  • 如果采用每秒定时推进,那么获取到第一个超时的任务列表时执行的200次推进中有199次属于“空推进”,而获取到第二个超时任务时有需要执行639次“空推进”,这样会无故空耗机器的性能资源,这里采用DelayQueue来辅助以少量空间换时间,从而做到了“精准推进”。

Kafka中的定时器可说是“知人善用”,用TimingWheel做最擅长的任务添加和删除操作,而用DelayQueue做最擅长的时间推进工作,相辅相成。

以上,是 Kafka 面试题【Kafka如何实现延迟队列】的参考答案。

输出,是最好的学习方法

欢迎在评论区留下你的问题、笔记或知识点补充~

—end—

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧