时间轮

原创 2018年04月15日 18:05:12

什么是时间轮

时间轮其实就是一种环形的数据结构,可以想象成时钟,分成很多格子,一个格子代码一段时间(这个时间越短,Timer的精度越高)。并用一个链表报错在该格子上的到期任务,同时一个指针随着时间一格一格转动,并执行相应格子中的到期任务。任务通过取摸决定放入那个格子。如下图所示:

时间轮

以上图为例,假设一个格子是1秒,则整个wheel能表示的时间段为8s,假如当前指针指向2,此时需要调度一个3s后执行的任务,显然应该加入到(2+3=5)的方格中,指针再走3次就可以执行了;如果任务要在10s后执行,应该等指针走完一个round零2格再执行,因此应放入4,同时将round(1)保存到任务中。检查到期任务时应当只执行round为0的,格子上其他任务的round应减1。

使用场景

  • 延迟队列,订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单。
  • 超时控制(xx分钟没有动作就断开连接)
  • 定时任务(5分钟后执行xx任务/每隔1天执行一次)

数据模型

public class HashWheelTimer {


    private Timer timer = new Timer();  //滚动装置

    private final long duration;    //每隔多少时间转动

    private final TimeUnit timeUnit;      //时间单位

    private int currentIndex;           //当前数组下表

    private final long wheelSize;          //时间轮大小

    private final Slot[] wheel;               //数组表示环形

    //初始化时间轮
    private static Slot[] createWheel(int wheelSize);

    //新建任务
    public Task newTask(Runable runable,long delay, TimeUnit unit){

    }

    //启动时间轮
    public void start(){
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                Slot slot = slots[currentIndex++];
                if(slot != null && slot.hasTask()){
                    //TODO something do slot
                }
                if(currentIndex >= wheelSize ){
                    currentIndex = 0;
                }
            }
        },1,timeUnit.toMillis(tickDuration));

    }

    //时间轮中的格子
    public class Slot {

        private Set<Task> tasks = new HashSet<>();

        //添加任务
        public synchronized void addTask(Task task);

        //是否有任务
        public boolean hasTask();
    }

    //任务
    public class Task {

        private Runable runable;

        private int cycleNum; //第几圈允许任务

    }

}

以上是我写的模型的抽离,具体实现可以参考Netty的HashedWheelTimer

案例

很多时候,业务有“在一段时间之后,完成一个工作任务”的需求。
例如:滴滴打车订单完成后,如果用户一直不评价,48小时后会将自动评价为5星。
一般来说怎么实现这类“48小时后自动评价为5星”需求呢?
常见方案:启动一个cron定时任务,每小时跑一次,将完成时间超过48小时的订单取出,置为5星,并把评价状态置为已评价。
假设订单表的结构为:t_order(oid, finish_time, stars, status, …),更具体的,定时任务每隔一个小时会这么做一次:
select oid from t_order where finish_time > 48hours and status=0;
update t_order set stars=5 and status=1 where oid in[…];
如果数据量很大,需要分页查询,分页update,这将会是一个for循环。

方案的不足:

(1)轮询效率比较低
(2)每次扫库,已经被执行过记录,仍然会被扫描(只是不会出现在结果集中),有重复计算的嫌疑
(3)时效性不够好,如果每小时轮询一次,最差的情况下,时间误差会达到1小时
(4)如果通过增加cron轮询频率来减少(3)中的时间误差,(1)中轮询低效和(2)中重复计算的问题会进一步凸显

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012092620/article/details/79951434

阿甘公益—“如何有效管理时间”

-
  • 1970年01月01日 08:00

高效定时器:时间轮和时间堆

游戏后台之高效定时器-时间轮 原文地址:http://blog.csdn.net/soft2967/article/details/9274691 高性能定时器 定时器的结构有多种,比如链表...
  • yang_chen_shi_wo
  • yang_chen_shi_wo
  • 2015-06-12 09:47:06
  • 2607

惊艳的时间轮定时器

http://www.cnblogs.com/zhongwencool/p/timing_wheel.html 问题引入:游戏里面每个Player身上有很多buffs,在每一个t...
  • woshiyuanlei
  • woshiyuanlei
  • 2016-07-15 15:26:39
  • 999

时间轮算法

时间轮是Linux中实现定时器的巧妙方式,也可以自己实现用于工程 可以参考http://www.ibm.com/developerworks/cn/linux/1308_liuming_linuxt...
  • mengdao2046
  • mengdao2046
  • 2016-06-02 00:09:52
  • 984

Timing Wheel 时间轮算法 java实现

原文地址:http://blog.csdn.net/mindfloating/article/details/8033340 最近自己在写一个网络服务程序时需要管理大量客户端连接的,其中每个客户...
  • yang_chen_shi_wo
  • yang_chen_shi_wo
  • 2015-06-16 16:49:34
  • 2765

简单时间轮算法

概念分析简单时间轮算法是时间轮算法的入门内容。笔者暂时研究到这块,下面做下详细的分享。时间轮算法:是指有一条时间闭环履带,每一节代表等长时间,假想有一个指针在这条履带圆心转动,转动速度恒定。当转到某一...
  • wltsysterm
  • wltsysterm
  • 2018-02-18 23:31:00
  • 165

TimingWheel[时间轮]介绍

Kafka的延迟操作是一个相对独立的组件,他的主要功能是管理延迟操作,底层依赖于Kafka提供的时间轮实现。JDK本身提供的java.util.Timer也可以实现定时任务,但是如果系统请求量巨大,性...
  • zhanglh046
  • zhanglh046
  • 2017-06-01 17:14:08
  • 2007

C时间轮

看完了《linux高性能服务器编程》对里面的定时器很感兴趣。书中提到三种定时器,分别是:基于升序链表的定时器,基于时间轮的定时器,基于时间堆的定时器。三种定时器的实现书中均是给了C++代码,不过我对C...
  • u012785877
  • u012785877
  • 2016-09-02 23:44:07
  • 1095

基于时间轮的定时器设计

转载地址:http://www.cnblogs.com/zhanghairong/p/3757656.html 在开发高性能服务器中,定时器总是不可或缺的。 常见的定时器实现三种,分别是:排序链...
  • u012398613
  • u012398613
  • 2016-07-20 08:48:47
  • 1426

linux的动态定时器--时间轮

定时器—有时也称为动态定时器或内核定时器—是管理内核时间的基础。定时器是一种软件功能,即允许在将来的某个时刻,函数在给定的时间间隔用完时被调用。注意的是定时器并不会周期运行,它在超时后就自行销毁,这也...
  • dndxhej
  • dndxhej
  • 2012-03-29 00:33:27
  • 6560
收藏助手
不良信息举报
您举报文章:时间轮
举报原因:
原因补充:

(最多只允许输入30个字)