时间轮-理论篇

article/2025/7/28 0:54:25

1. 引言

定时任务再开发过程中无处不在,定时发送消息,定时更新数据库表的状态,Linux系统定时执行脚本等等。这些操作都离不开定时任务,那么这些定时任务是怎么实现的是否又去想过。如果让开发者自己去实现一个定时任务又该怎么实现?

最简单的方案:定义一个链表,将要执行的任务添加到链表中。然后用线程去遍历链表,找出需要执行的任务进行执行。通过反复遍历任务链表就能实现定时任务的执行功能。

在这里插入图片描述

但是上述方案有一个很重要的缺陷:如果我的任务有上百万个甚至更多的情况下,可能光遍历整个链表找出需要执行的任务就要花费一定量的时间。如果此时刚好有一个任务添加到链表的Tail,但是任务扫描的指针此时刚好在第一个Head任务节点。此时添加的任务执行时间就在添加后的20ms后,这个时候线程扫描到最后一个需要执行的任务的耗时可能超过了20ms,那么这种情况下就会出现任务的延迟执行。

Tips: 任务的延迟执行需要有一个合理的容忍范围。

在论文《Hashed and Hierarchical Timing Wheels》 提出了时间轮的概念来解决传统定时任务中的弊端

2. 时间轮简介

在生活中大家肯定见过指针手表(非电子手表)这个就可以看做时间轮,山地自行车的前后齿轮、水表的齿轮、以及减速齿轮都可以看做是时间轮。以手表的刻度为例子,机械手表上最长的指针每条以下表示1秒,也就是将一分钟分成了60个1秒。 时间轮的核心思想:将单位时间分成若干个时间间隔,每个时间间隔包含了时间单位除以若干时间间隔的时间量,时间轮转动到对应的时间间隔就执行当前时间间隔对应的可执行的任务。

下面用例子来说明:

1秒我们可以分成8个时间间隔,那么每个时间间隔就是125ms,如下图所示:

在这里插入图片描述

2.1 简单的时间轮

在论文《Hashed and Hierarchical Timing Wheels》 中每一个时间间隔叫做 bucket 。 bucket的作用用于存放当前时间间隔内存在的需要执行的任务。例如现在有四个任务A、B、C、D分别要在一秒的三个不同的时间段执行,A、B在两个不同的时间段执行,C、D在同一个时间段执行。那么在时间轮上的示意图如下:

在这里插入图片描述

当时间轮的指针从1Bucket的开始时间到结束时间段的过程中,会去遍历Bucket的链表中的任务,将需要执行的任务从链表中拿出来执行。已上图的例子每一秒时间轮的指针走一圈。

Tips: bucket中存放的任务是时间轮一个时间间隔中的任务,也就是说这些任务是一个时间段里面的任务。例如:100ms和80ms需要执行的任务都说存在bucket1。

进一步思考,如果你一分钟执行一次,那么时间轮的刻度就需要分成480个时间段,随着单位时间刻度的增加会让时间论的刻度越来越多。这样对于计算机来说就是消耗更多的内存。这种如何解决,在论文中提出另一个概念就是:分层时间轮

2.2 分层时间轮

在生活中分层时间轮也是比比皆是,例如在手表长最长的指针代表秒针,中间的代表分针,最短的代表时针。例如我有三个任务 A、B、C分别在以下时间执行:

  • A六十秒的时候执行一次
  • B十五分钟的时候执行一次
  • C六点位置的时候执行一次

如下图所示:

在这里插入图片描述

秒时间轮完成一圈触发分时间轮刻度往下一个,分时间轮完成一周触发时时间轮往下一个刻度。分层时间轮之间的刻度关系可以自己定义。不需要和时间刻度表上一样的。具体取决于业务的需要。例如:Linux的Corntab只支持分钟,而Java的Quartz可以支持到秒。

3.总结

时间轮是一种高效来利用线程资源来进行批量化调度的一种调度模型。提高利用率,但是时间轮调度器的时间精度可能不是很高,对于精度要求特别高的调度任务可能不太适合。因为时间轮算法的精度取决于,也就是时间间隔,时间间隔越小精度越高。时间轮的使用在各大框架与中间件中有使用,netty,kafka,jraft(这个是fork netty的)。

度越高。时间轮的使用在各大框架与中间件中有使用,netty,kafka,jraft(这个是fork netty的)。

我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢!


http://chatgpt.dhexx.cn/article/l9g2qJ9L.shtml

相关文章

定时任务的实现原理:时间轮算法

文章目录 前言时间轮定时使用方式时间轮定时内部原理时间轮定时源码剖析构造方法添加任务工作线程启动工作线程run方法指针跳动将队列任务放入时间轮中链表任务遍历定时任务执行 前言 最近在思考实现定时任务的几种方式,比如 quartz,delay queue&#xf…

时间轮-Java实现篇

在前面的文章《时间轮-理论篇》讲了时间轮的一些理论知识,然后根据理论知识。我们自己来实现一个简单的时间轮。 1. 理论抽象 将时间轮的理论进行抽象,主要有两个方面: 时间轮的转动每一个时间间隔任务的处理,从时间间隔的Buke…

时间轮timewheel算法

时间轮是个不太常见,但在部分场景有较高使用价值的工具。 时间轮常用于延时任务,在Netty、akka、Quartz、Zookeeper等高性能组件中都存在时间轮定时器的踪影。 从定时任务说起 自然界中定时任务无处不在,太阳每天东升西落,候鸟的…

定时器实现原理——时间轮

时间轮 时间轮算法是通过一个时间轮去维护定时任务,按照一定的时间单位对时间轮进行划分刻度。然后根据任务延时计算任务落在该时间轮的第几个刻度上,如果任务时长超出了刻度数量,则需要增加一个参数记录时间轮需要转动的圈数。 简单时间轮…

时间轮算法

一、时间轮算法 1. 时间轮的基本概念 Kafka中存在大量的延时操作,如延时生产、延时消费等;而JDK中自带的 Timer 和 DelayQueue 的插入和删除操作的平均复杂度为 O(nlogn),无法满足 Kafka 的高性能要求,因…

时间轮算法(TimingWheel)

时间轮算法的应用非常广泛,在 Dubbo、Netty、Kafka、ZooKeeper、Quartz 的组件中都有时间轮思想的应用,甚至在 Linux 内核中都有用到。 其思想理论基础可以参考论文:http://www.cs.columbia.edu/~nahum/w6998/papers/ton97-timing-wheels.pd…

那些惊艳的算法们(三)—— 时间轮

从定时任务说起 自然界中定时任务无处不在,太阳每天东升西落,候鸟的迁徙,树木的年轮,人们每天按时上班,每个月按时发工资、交房租,四季轮换,潮涨潮落,等等,从某种意义上…

1、时间轮

一、什么是时间轮? 作为一个粗人,咱不扯什么高级的词汇,直接上图: 上面是一张时间轮的示意图,可以看到,这个时间轮就像一个钟表一样,它有刻度,图中画了9个格子,每个格子…

浅谈时间轮算法

浅谈时间轮算法 基于队列的定时任务执行模型缺陷 在计算机世界中,只有待解决的问题变得大规模后,算法的价值才能够最大化的体现。时间轮算法可以将插入和删除操作的时间复杂度都降为 O(1),在大规模问题下还能够达到非常好的运行效果。 如果…

时间轮(TimingWheel)算法总结

通过阅读篇文章您可以很容易理解平时所使用的开源框架是如何进行任务调度的。而且对于以后业务上碰到需要做时间任务调度的需求,也可以尝试着用实践论算法去实现。 一、时间轮的应用 其实早在1987年,时间轮算法的论文已经发布。论文名称:Hash…

时间轮 (史上最全)

缓存之王 Caffeine 中,涉及到100w级、1000W级、甚至亿级元素的过期问题,如何进行高性能的定时调度,是一个难题。 注: 本文从 对 海量调度任务场景中, 高性能的时间轮算法, 做了一个 系统化、由浅入深的 穿透…

时间轮(Timing Wheel)案例和原理

什么是时间轮(Timing Wheel) 时间轮(Timing Wheel)是George Varghese和Tony Lauck在1996年的论文Hashed and Hierarchical Timing Wheels: data structures to efficiently implement a timer facility实现的,它在Linux内核中使用广泛,是Linux内核定时器…

时间轮(TimingWheel)

一、什么是时间轮 时间轮其实就是一种环形的数据结构,可以想象成时钟,分成很多格子,一个格子代表一段时间(这个时间越短,Timer的精度越高)。并用一个双向链表存储放在该格子上的延时任务,同时一…

高性能定时器3——时间轮

​ 在网络程序中我们通常要处理三种事件,网络I/O事件、信号以及定时事件,我们可以使用I/O复用系统调用(select、poll、epoll)将这三类事件进行统一处理。我们通常使用定时器来检测一个客户端的活动状态,服务器程序通常…

C#,斐波那契数列(Fibonacci Sequence)的八种算法与源代码

一、莱昂纳多斐波那契(Leonardo Fibonacci) 斐波那契公元1170年生于意大利比萨,卒于1250年,被人称作“比萨的莱昂纳多”,是一名闻名于欧洲的数学家,其主要的著作有《算盘书》、《实用几何》和《四艺经》等。…

matlab斐波那契数列画图,斐波拉契数列 斐波那契数列 matlab程序

斐波那契数列数列从第3项开始,每一项都等于前两项之和。 例子:数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368 应用: 生活斐波那契 斐波那契数列中的斐波脾气有点大,表面温和到别人误以为很好欺…

快速计算斐波那契数列(Fibonacci数列)

本文最后更新于 619 天前,其中的信息可能已经有所发展或是发生改变。 题目描述 输入一个正整数n,求Fibonacci数列的第n个数。Fibonacci数列的特点:第1,2个数为1,1。从第3个数开始,概述是前面两个数之和。即: 要求输入的…

递归求斐波那契数列

斐波那契数列 题目描述:编写一个函数,求斐波那契数列的第n项的值。 首先,对于斐波那契数列,我们是非常熟悉了,对斐波那契定义为如下:f(0)0,f(1)0,f(2)1,……f(n)f(n-1)f(n-2),其中n>1。对于这…

斐波那契数列(Fibonacci)

有一对兔子,出生后第3个月起每个月都生一对免子。小兔子长到第3个月后每个月又生一对兔子。假设所有兔子都不死,问40个月的免子总数为多少?解题思路: 这是一个有趣的古典数学问题。可以从表1看出兔子繁殖的规律。 …

【递归 动态规划 备忘录法】Fibonacci数列(斐波那契数列)(C++)

一、什么是Fibonacci数列 斐波那契数列指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…用文字来说,就是从第3项开始,每一项都等于前两项之和。至于包不包括0,一番查阅后没有得到证实… 不过重要的是“第3项开始…