6.2 8 时间轮
Kafka中存在大量的延时操作, 比如延时生产、延时拉取和延时删除等。
Kafka并没有使用
JDK自带的Timer 或DelayQueue来实现延时的功能,而是基于时间轮的概念自定义实现了一个
用千延时功能的定时器(SystemTimer)。
JDK中Timer和DelayQueue的插入和删除操作的平
均时间复杂度为O(nlogn)并不能满足Kafka的高性能要求, 而基于时间轮可以将插入和删除操
作的时间复杂度都降为0(1) 。
时间轮的应用并非Kafka独有, 其应用场景还有很多,在Netty、
Akka、Quartz、ZooKeeper等组件中都存在时间轮的踪影。
如图6-7所示, Kafka中的时间轮(TimingWheel)是一个存储定时任务的环形队列, 底层
采用数组实现, 数组中的每个元素可以存放一个定时任务列表(TimerTaskList)。TimerTaskL闵
是一个环形的双向链表,链表中的每一项表示的都是定时任务项(TimerTaskEntry), 其中封装
了真正的定时任务(TimerTask)。
时间轮由多个时间格组成, 每个时间格代表当前时间轮的基本时间跨度(tickMs)。时间
轮的时间格个数是固定的,可用wheelSize来表示, 那么整个时间轮的总体时间跨度(interval)
可以通过公式tickMsXw heelSize计算得出。 时间轮还有 一个表盘指针(currentTime) , 用来表
示时间轮当前所处的时间,currentTime 是tickMs的整数倍。currentTime可以将整个时间轮划分
为到期部分和未到期部分, currentTime当前指向的时间格也属千到期部分, 表示刚好到期, 需
要处理此时间格所对应的TimerTaskList中的所有任务。