当前位置: 首页 > news >正文

吃透大数据算法-时间轮(TimingWheel)

0、故事背景

在城市的角落,有个特殊的 “Kafka 消息驿站”—— 它不送实体包裹,专送 “数据消息”:比如电商的订单通知、社交软件的聊天消息、物流的状态更新。驿站老板老 K 最近愁坏了三件事:

  1. 有些消息要 “延迟送”(比如用户设置 “10 分钟后提醒付款”);
  2. 要确认分店(副本)是否收到消息,超时没收到得重发;
  3. 过期消息(比如存了 7 天的旧日志)得按时清理,占地方。

“总不能雇人盯着时钟吧?” 老 K 的侄子小 K 是程序员,搬来一个三层的 “智能调度盘”:“这是时间轮,能自动管所有定时任务,比 10 个员工还靠谱!”

一、先搞懂:Kafka 为啥非要用时间轮?

小 K 先给老 K 算笔账:驿站每天要处理百万级定时任务(延迟消息、超时检测、过期清理)。如果用 “一个任务一个闹钟”(比如 Java 的Timer),会占满内存和 CPU—— 就像给每个包裹单独雇个快递员,成本高到离谱。

“时间轮就像‘共享快递员’,把任务按时间分组,一批批处理。” 小 K 指着调度盘:“Kafka 里所有定时任务,全靠它高效运转,还不浪费资源。”

二、时间轮基础概念:我们每天都在见?

时间轮的基本结构

  • 环形数组(时间轮主体): 一个环形的数组结构,被均匀地分割成多个槽位(slot),每个槽位代表一个时间间隔。
  • 指针(时间推进器): 一个表示当前时间的指针,随着时间的推进在环形数组上移动。
  • 任务列表: 每个槽位中可以存储一个任务列表,用于存放需要在该时间点执行的所有任务。
时间间隔(tick)

每个槽位代表的时间长度,也称为时间轮的粒度。

示例:10分钟

决定时间轮的时间精度

槽位数量(wheelSize)

环形数组的槽位总数。

示例:12个槽位

决定时间轮能够表示的最大时间范围

时间范围(interval)

整个时间轮能够表示的时间跨度。

计算公式:时间间隔 × 槽位数量

示例:10分钟 × 12 = 120分钟

这三个参数之间存在权衡关系。时间间隔越小,时间精度越高,但所能表示的时间范围就越小;槽位数量越多,时间范围越大,但内存占用也会增加。需要根据实际需求来选择合适的参数

多层时间轮概念

为了解决单层时间轮时间范围有限的问题,可以引入多层时间轮的设计,类似于钟表的秒针、分针和时针:

  • 第一层(秒轮):60个槽位,每个槽位1秒,覆盖0-59秒
  • 第二层(分轮):60个槽位,每个槽位1分钟,覆盖0-59分钟
  • 第三层(时轮):24个槽位,每个槽位1小时,覆盖0-23小时

在多层时间轮中,每一层的时间跨度是上一层的60倍。当高层时间轮的指针转动一格时,意味着下一层时间轮已经转完了一圈。

三、Kafka 的时间轮:三层 “转盘” 搞定所有时间尺度

Kafka 用的是多层时间轮(比之前社区的 “大中小板” 更精细),三层转盘分别对应 “毫秒级”“秒级”“分钟级”,完美覆盖 Kafka 的所有定时场景。

小 K 在转盘上贴了标签,对应 KafkaSystemTimer类的核心参数:

转盘层级最小时间单位(tickMs)槽位数量(wheelSize)总覆盖时间(interval = tickMs×wheelSize)负责的任务类型
第一层(小转盘)100ms(0.1 秒)202000ms(2 秒)2 秒内的紧急任务(如副本同步超时检测)
第二层(中转盘)2000ms(2 秒)2040000ms(40 秒)2 秒 - 40 秒的常规任务(如短延迟消息)
第三层(大转盘)40000ms(40 秒)20800000ms(约 13 分钟)40 秒 - 13 分钟的长任务(如消息过期清理)

“如果任务超过 13 分钟呢?” 老 K 问。“大转盘转满一圈(13 分钟),就自动‘叠一层’—— 相当于再套一个‘超大转盘’,理论上能管到天级任务!” 小 K 补充。

四、实战:Kafka 用时间轮处理 3 类核心任务

小 K 拿驿站的 3 个难题举例,演示时间轮怎么干活:

任务 1:延迟消息(“10 分钟后送的订单提醒”)

用户提交了一条 “10 分钟后(600000ms)发送的订单支付提醒”,小 K 演示流程:

  1. 算槽位,找层级

    • 大转盘 interval=13min(780000ms),600000ms < 780000ms,所以先放大转盘;
    • 大转盘 tickMs=40000ms,需要槽位 = 600000ms ÷ 40000ms = 15 槽;
    • 把 “订单提醒” 任务放进大转盘的第 15 槽,标记 “还剩 15 格触发”。
  2. 转盘转动,任务 “降级”

    • 大转盘每 40 秒转 1 格,转 14 格后(14×40=560 秒),任务还剩 1 格(40 秒);
    • 此时任务 “降级” 到中转盘:中转盘 tickMs=2000ms,40 秒 = 20 槽,放进中转盘第 20 槽。
  3. 再降级,到小转盘

    • 中转盘每 2 秒转 1 格,转 19 格后(38 秒),任务还剩 1 格(2 秒);
    • 任务再 “降级” 到小转盘:小转盘 tickMs=100ms,2 秒 = 20 槽,放进小转盘第 20 槽。
  4. 触发执行

    • 小转盘每 100ms 转 1 格,转 20 格后(2 秒),触发任务:把 “订单提醒” 消息投递给目标 Topic,完成延迟发送。

任务 2:副本同步超时(“分店没收到消息,3 秒后重发”)

驿站的 “北京分店”(Partition 副本)要接收 “上海总部”(Leader 副本)的消息,规定 3 秒内没收到要重发 —— 这就是 Kafka 的replica.lag.time.max.ms配置。时间轮处理流程:

  1. 总部发送消息后,把 “3 秒(3000ms)超时检测” 任务放进中转盘(3000ms > 小转盘 2s,所以进中转盘);
  2. 中转盘 tickMs=2s,3000ms=1×2000ms+1000ms,放进中转盘第 1 槽,标记 “1 格后降级到小转盘第 10 槽”;
  3. 1 格后(2 秒),任务降级到小转盘第 10 槽(1000ms=10×100ms);
  4. 小转盘转 10 格(1 秒)后,若还没收到分店的 “确认收到” 信号,触发 “重发消息” 任务。

任务 3:消息过期清理(“7 天后删除旧日志”)

Kafka 的消息默认存 7 天(log.retention.hours=168),过期要删除 —— 这是长周期任务,时间轮处理更简单:

  1. 消息写入时,把 “7 天后删除” 任务放进高层转盘(超过 13 分钟,自动扩展 “超大转盘”,tickMs=13min,wheelSize=20,interval=260min);
  2. 高层转盘每 13 分钟转 1 格,转 672 格后(7×24×60÷13≈672),任务逐步降级到中转盘、小转盘;
  3. 最终到小转盘触发时,调用LogCleaner线程,删除该 Partition 的过期日志文件。

五、Kafka 时间轮的 “黑科技”:3 个优化点

老 K 好奇:“这么多任务,转盘会不会卡壳?” 小 K 笑着指了指转盘的细节,这是 Kafka 时间轮的独家优化:

1. 溢出槽:用 “备用盒” 装超高层任务

如果有个 “30 天的延迟消息”(远超当前所有层级),时间轮会先把它放进溢出槽(对应 Kafka 里的DelayQueue)—— 就像驿站的 “备用盒”,每过一段时间(比如 1 分钟),把备用盒里的任务重新算槽位,分配到对应层级。“这样就不会丢任务,也不用一开始就建几十层转盘!”

2. 批量处理:一次搬一堆任务,不浪费时间

小 K 演示:当中转盘转 1 格时,会把该槽里的 10 个 “降级任务” 一次性搬到小转盘,而不是一个一个搬 —— 就像快递员一次拉 10 个包裹,不是跑 10 趟。Kafka 通过这种 “批量降级、批量执行”,把任务处理效率提了 10 倍。

3. 单线程驱动:一个 “调度员” 管所有转盘

所有转盘的指针,都由一个线程(Kafka 的TimerThread)驱动 —— 就像一个调度员管 3 个转盘,不用雇 3 个调度员。这样既减少线程切换开销,又避免多线程同步的麻烦。

六、Kafka 时间轮的 “核心价值”

老 K 看着自动运转的调度盘,感慨道:“原来 Kafka 的高效,全靠这‘多层转盘’啊!” 小 K 总结了 3 个核心价值:

  1. 省资源:百万级任务共用一个时间轮,不用 “一个任务一个线程”,内存和 CPU 占用骤降;
  2. 全覆盖:多层结构能管 “毫秒级” 到 “天级” 任务,适配 Kafka 所有定时场景;
  3. 高可靠:溢出槽 + 批量处理,既不丢任务,又能快速响应。

最后,小 K 补充:“Kafka 的时间轮实现类是org.apache.kafka.common.utils.SystemTimer,核心就是‘多层 + 延迟队列’—— 你看到的‘智能调度盘’,就是它的现实版!”

从那以后,Kafka 消息驿站再也没漏过一个延迟消息、没误删一条日志,老 K 终于能睡个安稳觉了 —— 这就是时间轮在 Kafka 里的 “魔力”。

七、时间轮的 3 大变种:适配日常不同时长的提醒

变种类型核心特点(对应日常时钟)注意点(实际使用坑)调优点(让提醒更准)
单层时间轮就像一个 “1 小时小闹钟”(12 槽 ×5 分钟 = 60 分钟),超 1 小时的任务记 “圈数”(如 90 分钟 = 1 圈 + 30 分钟)超 2 小时的任务要记 “2 圈”,指针每转 1 圈都要改圈数,容易漏改1. 把槽位时间调大(如 10 分钟 / 槽,12 槽覆盖 2 小时),减少圈数;2. 槽位数量和时钟刻度一致(12/24),方便记
多层时间轮像家里的 “闹钟 + 挂钟 + 日历” 组合:- 第一层(5 分钟轮):12 槽 ×5=60 分钟(对应分针)- 第二层(小时轮):12 槽 ×1=12 小时(对应时针)- 第三层(天轮):2 槽 ×12=24 小时(对应日历半天)低层转满 1 圈,触发高层转 1 格(如 5 分钟轮转 12 圈 = 1 小时,小时轮转 1 格)高层转格时,要把低层 “刚转完的槽位任务” 搬到高层,比如 5 分钟轮转完 1 圈,要把 “1 小时后” 的任务移到小时轮,搬慢了会延迟1. 按日常任务分布调槽数:比如小时轮设 24 槽(对应 24 小时),不用记上下午;2. 高层转格时 “批量搬任务”(比如凑够 5 个再搬),减少麻烦
带溢出槽的时间轮一个 “2 小时时钟轮”(24 槽 ×5 分钟 = 120 分钟)+ 一个 “待办盒”(溢出槽):超 2 小时的任务先放 “待办盒”,每 2 小时(时钟轮转满 1 圈),再把 “待办盒” 里的任务重新算槽位(如 3 小时任务→1 圈 + 1 小时→槽 12)“待办盒” 里的任务要等 1 圈(2 小时)才重新算,可能多等 5-10 分钟1. 按最长提醒时间调轮的覆盖范围:比如常提醒 3 小时内的包裹,就做 “3 小时轮”(36 槽 ×5 分钟);2. “待办盒” 每 30 分钟查一次,不用等满 1 圈

八、其他组件的使用

组件 / 工具用的变种类型具体用途(对应日常时间)为啥选时间轮?(日常类比)
Netty带溢出槽的单层轮管理网络连接超时(如 30 秒没响应就断开)像驿站 “30 分钟短信提醒”,短时间任务多,用小轮 + 待办盒高效
Kafka多层时间轮管理消息过期删除(如 7 天后自动删旧消息)像 “24 小时退回包裹”,时间跨度大(天级),用多层轮不用记圈数
ZooKeeper单层时间轮检测客户端是否在线(如 10 分钟没心跳就踢掉)像 “2 小时打电话提醒”,时间中等(分钟 - 小时级),单层轮够简单
Redis类似单层轮结构清理过期的缓存数据(如 1 小时后失效的缓存)像 “1 小时后检查包裹”,任务多但时间短,用时钟轮省力气
Quartz多层时间轮定时跑报表(如每天凌晨 2 点生成前一天报表)像 “每天固定时间盘点”,周期长(天级),多层轮能精准到小时

总结:时间轮就是 “技术版的时钟”

老K现在看着墙上的 “时钟提醒器”,再也不用记时间了:“原来这玩意儿和家里的钟一样,指针转一圈,该做的事就到点了!”

其实时间轮的核心,就是把 “复杂的定时任务” 变成 “日常看钟”—— 用循环的刻度(槽位)复用资源,用多层级(时分天)处理长周期,就像你不用记 “100 分钟后做什么”,只要看 “1 小时 40 分钟后,对应时钟的哪个刻度” 一样,简单又高效。

(欢迎订阅本专栏)

http://www.dtcms.com/a/442162.html

相关文章:

  • 从输入URL到展示出页面的这个过程~
  • WebDAV 与 SMB 在钓鱼攻击中的区别
  • 8. Pandas 日期与时间序列数据处理
  • 免费网站模板做零食的网站有哪些
  • 从零开始的C++学习生活 2:类和对象(上)
  • 家纺营销型网站网站建设服务费怎么记账
  • css其他选择器(精细修饰)
  • 一般设计网站页面用什么软件做引擎网站
  • 生成式 AI 重构内容创作:从辅助工具到智能工厂
  • 华为S5720配置telnet远程
  • 面试复盘:哔哩哔哩、蔚来、字节跳动、小红书面试与总结
  • Your ViT is Secretly an Image Segmentation Model
  • 海口网站建设运营网站开发公司选择
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(4):语法 +考え方17+2022年7月N1
  • RAG:解锁大语言模型新能力的关键钥匙
  • 广州网站建设海珠信科网站建设推广方法
  • Oracle Linux 7.8 静默安装 Oracle 11g R2 单机 ASM 详细教程
  • 旅游公司网站建设方案网站的布局结构三种
  • Django ORM 无法通过 `ForeignKey` 自动关联,而是需要 **根据父模型中的某个字段(比如 ID)去查询子模型**。
  • 吉林省建设厅信息网站网站建设的评价
  • 分布式专题——26.5 一台新机器进行Web页面请求的历程
  • 怎么让别人看到自己做的网站万维网网站301重定向怎么做
  • css样式学习记录
  • 网站服务器关闭网站数据库地址是什么
  • 每日一个C语言知识:C程序结构
  • Amazon RDS:云端数据库管理的革新之路
  • wordpress登录可见站内seo是什么意思
  • STM32简单的串口Bootloader入门
  • 360网站怎么做2核4g做网站
  • 从 “手工作坊” 到 “智能工厂”:2025 年 AI 原生应用重构内容创作产业