定时任务的分布式调度

转自:https://www.cnblogs.com/haoxinyue/p/6886196.html

单机定式任务调度的问题

在很多应用系统中我们常常要定时执行一些任务。比如,订单系统的超时状态判断、缓存数据的定时更新、定式给用户发邮件,甚至是一些定期计算的报表等等。常见的处理方式有线程的while(true) 和sleep组合、使用Timer定时器触发任务又或者是使用quartz框架。貌似这些方法可以完美的解决方案,为什么还需要分布式呢?主要有如下两点原因:

1.高可用:单机版的定式任务调度只能在一台机器上运行,如果程序或者系统出现异常就会导致功能不可用。虽然可以在单机程序实现的足够稳定,但始终有机会遇到非程序引起的故障,而这个对于一个系统的核心功能来说是不可接受的。

2.单机处理极限:原本1分钟内需要处理1万个订单,但是现在需要1分钟内处理10万个订单;原来一个统计需要1小时,现在业务方需要10分钟就统计出来。你也许会说,你也可以多线程、单机多进程处理。的确,多线程并行处理可以提高单位时间的处理效率,但是单机能力毕竟有限(主要是CPU、内存和磁盘),始终会有单机处理不过来的情况。

这个时候就需要分布式的定时任务来实现了。业内常用的分布式定式任务解决方案主要有quartz、淘宝的TBSchedule和当当的elastic-job。

quartz的集群解决方案

quartz的单机版本大家应该比较熟悉,它的集群方案是使用数据库来实现的。集群架构如下:

上图三个节点在数据库中都拥有同一份Job定义,如果某一个节点失效,那么Job会在其他节点上执行。由于三个节点上的Job执行代码是一样的,那么怎么保证只有在一台机器上触发呢?答案是使用了数据库锁。在quartz的集群解决方案里有张表scheduler_locks,quartz采用了悲观锁的方式对triggers表进行行加锁,以保证任务同步的正确性。一旦某一个节点上面的线程获取了该锁,那么这个Job就会在这台机器上被执行,同时这个锁就会被这台机器占用。同时另外一台机器也会想要触发这个任务,但是锁已经被占用了,就只能等待,直到这个锁被释放。之后会看trigger状态,如果已经被执行了,则不会执行了。

简单地说,quartz的分布式调度策略是以数据库为边界资源的一种异步策略。各个调度器都遵守一个基于数据库锁的操作规则从而保证了操作的唯一性。同时多个节点的异步运行保证了服务的可靠。但这种策略有自己的局限性:集群特性对于高CPU使用率的任务效果很好,但是对于大量的短任务,各个节点都会抢占数据库锁,这样就出现大量的线程等待资源。这种情况随着节点的增加会越来越严重。

另外,quartz的分布式只是解决了高可用的问题,并没有解决任务分片的问题,还是会有单机处理的极限。

TBSchedule

TBSchedule是一款非常优秀的高性能分布式调度框架,广泛应用于阿里巴巴、淘宝、支付宝、京东、聚美、汽车之家、国美等很多互联网企业的流程调度系统。tbschedule在时间调度方面虽然没有quartz强大,但是它支持分片功能。和quartz不同的是,tbschedule使用ZooKeeper来实现任务调度的高可用和分片。

TBSchedule的分布式机制是通过灵活的Sharding方式实现的,分片的规则由客户端决定,比如可以按所有数据的ID按10取模分片、按月份分片等等。TBSchedule的宿主服务器可以进行动态扩容和资源回收,这个特点主要是因为它后端依赖的ZooKeeper,这里的ZooKeeper对于TBSchedule来说是一个NoSQL,用于存储策略、任务、心跳信息数据,它的数据结构类似文件系统的目录结构,它的节点有临时节点、持久节点之分。调度引擎启动后,随着业务量数据量的增多,当前Cluster可能不能满足目前的处理需求,那么就需要增加服务器数量,一个新的服务器上线后会在ZooKeeper中创建一个代表当前服务器的一个唯一性路径(临时节点),并且新上线的服务器会和ZooKeeper保持长连接,当通信断开后,节点会自动摘除。

TBSchedule会定时扫描当前服务器的数量,重新进行任务分配。TBSchedule不仅提供了服务端的高性能调度服务,还提供了一个scheduleConsole的war包,随着宿主应用的部署直接部署到服务器,可以通过web的方式对调度的任务、策略进行监控管理,以及实时更新调整。

elastic-job

Elastic-Job当当开源的分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。一般我们只要使用Elastic-Job-Lite就好。

Elastic-Job-Lite并没有宿主程序,而是基于部署作业框架的程序在到达相应时间点时各自触发调度。它的开发也比较简单,引用Jar包实现一些方法即可,最后编译成Jar包运行。Elastic-Job-Lite的分布式部署全靠ZooKeeper来同步状态和原数据。实现高可用的任务只需将分片总数设置为1,并把开发的Jar包部署于多个服务器上执行,任务将会以1主N从的方式执行。一旦本次执行任务的服务器崩溃,其他执行任务的服务器将会在下次作业启动时选择一个替补执行。如果开启了失效转移,那么功能效果更好,可以保证在本次作业执行时崩溃,备机之一立即启动替补执行。

Elastic-Job-Lite的任务分片也是通过ZooKeeper来实现,Elastic-Job并不直接提供数据处理的功能,框架只会将分片项分配至各个运行中的作业服务器,开发者需要自行处理分片项与真实数据的对应关系。框架也预置了一些分片策略:平均分配算法策略,作业名哈希值奇偶数算法策略,轮转分片策略。同时也提供了自定义分片策略的接口。

另外Elastic-Job-Lite还提供了一个任务监控和管理界面:Elastic-Job-Lite-Console。它和Elastic-Job-Lite是两个完全不关联的应用程序,使用ZooKeeper来交换数据,管理人员可以通过这个界面查看、监控和管理Elastic-Job-Lite的任务,必要的时候还能手动触发任务。

elastic-job结合了quartz非常优秀的时间调度功能,并且利用ZooKeeper实现了灵活的分片策略。除此之外,还加入了大量实用的监控和管理功能,以及其开源社区活跃、文档齐全、代码优雅等优点,是分布式任务调度框架的推荐选择。

Saturn

Saturn是唯品会在github开源的一款分布式任务调度产品。它是基于当当elastic-job来开发的,其上完善了一些功能和添加了一些新的feature。目前在github上开源大半年,470个star。Saturn的任务可以用多种语言开发比如python、Go、Shell、Java、Php。其在唯品会内部已经发部署350+个节点,每天任务调度4000多万次。同时,管理和统计也是它的亮点。

有兴趣的同学可以从https://github.com/vipshop/Saturn 上了解更加详细的信息。

原文地址:https://www.cnblogs.com/xifenglou/p/8429269.html

时间: 2024-12-24 20:49:23

定时任务的分布式调度的相关文章

我的物联网项目(八)简单分布式调度

定时调度基本在任何平台或多或少的要用到,实现定时调度的功能很简单,我做过的项目中用到更多的是spring quartz或者spring task,它们在单机上使用定时任务配置是非常简单的,但是在集群环境中就需要面临一个必须解决的问题:如何限定只有一台机器在执行定时任务? 其实spring quartz也可以实现此功能,它是由数据库的数据来确定调度任务是否正在执行, 正在执行则其他服务器就不能去执行该行调度数据,所以需要数据库的11张表来执行此种功能,总的来说成本较高,操作起来也比较复杂.另外一些

详解应对平台高并发的分布式调度框架TBSchedule

tbschedule是一款非常优秀的高性能分布式调度框架,非常高兴能分享给大家.这篇文章是我结合多年tbschedule使用经验和研读三遍源码的基础上完成的,期间和阿里空玄有过不少技术交流,非常感谢空玄给予的大力支持.我写这篇文章的目的一是出于对tbschedule的一种热爱,二是现在是一个资源共享.技术共享的时代,希望把它展现给大家(送人玫瑰,手留余香),能给大家的工作带来帮助. 一.tbschedule初识 时下互联网和电商领域,各个平台都存在大数据.高并发的特点,对数据处理的要求越来越高,

Spring 的@Scheduled注解实现定时任务执行和调度

首先要配置我们的spring.xml   ---  即spring的主配置文件(有的项目中叫做applicationContext.xml或context.xml) xmlns 多加下面的内容. [html] view plaincopy xmlns:task="http://www.springframework.org/schema/task" 然后xsi:schemaLocation多加下面的内容. [html] view plaincopy http://www.springf

分布式调度

分布式调度两大任务: 任务调度:大量计算任务.任务如何切分.数据如何分割.运算.监控运算状态. 资源调度 1.任务调度 2.资源调度 3.容错机制 4.规模挑战 5.安全与性能隔离 6.分布式调度发展方向 在VLDB 2014 Fuxi论文 http://www.vldb.org/pvldb/vol7/p1393-zhang.pdf 原文地址:https://www.cnblogs.com/jiweilearn/p/8908277.html

分布式调度QUARTZ+SPRING

使用SPRING的定时任务框架,如果是在分布式的环境下,由于有多台节点,会产生相同的任务,会被多个节点执行,这时需引入分布式的QUARTZ. 触发器:存放时间排程 任务:蔟业务代码 排程器:负责调度,即在指定的时间执行对应的任务 如果是分布式QUARTZ,则各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务. 如果此节点执行失败,则此任务则会被分派到另一节点执行. quartz.properties # =======

spring定时任务之-quartz调度器

公司项目里面有个定时任务,一直想弄清楚其流程,以为很难,今天有空研究了一下,发现其实实现很简单. 查资料发现spring的定时任务有很多种,quartz调度器也有两种一种是作业类需继承自特定的基类:org.springframework.scheduling.quartz.QuartzJobBean. 另一种则是作业类不需继承特定基类.我觉得第二种更加简单简洁,公司项目里面也是用到的这种方法.接下来就讲一下具体编写步骤: 第一步:编写任务类 Java代码   package com.grx.pa

Spring 的@Scheduled注解实现定时任务运行和调度

首先要配置我们的spring.xml   ---  即spring的主配置文件(有的项目中叫做applicationContext.xml或context.xml) xmlns 多加以下的内容. [html] view plaincopy xmlns:task="http://www.springframework.org/schema/task" 然后xsi:schemaLocation多加以下的内容. [html] view plaincopy http://www.springf

分布式调度任务

https://www.jianshu.com/p/3be513581027 http://qinghua.github.io/spring-scheduler/ https://www.cnblogs.com/hongwz/p/5642429.html https://blog.csdn.net/quwenzhe/article/details/78865875 原文地址:https://www.cnblogs.com/zgzf/p/10641629.html

分布式调度平台XXL-JOB源码分析-重试机制

在我们XxlJobScheduler类中,会启动一个失败任务监控线程,本文就来分析JobFailMonitorHelper这个类 原文地址:https://www.cnblogs.com/jiangyang/p/11597800.html