散布式任务调度是非常常见的1种利用场景,1般对可用性和性能要求不高的任务,采取单点便可,例如linux的crontab,spring的quarz,但是如果要求部署多个节点,到达高可用的效果,上面的方案就不适用了。
实际上任务调度的实现有两种情况,第1种是通过mq来实现,mq做好了数据切分,负载均衡的效果,本文说的是另外一种情况。
1、不重复
如果只到达这个要求,有很多方法,假定任务处理的是1张表中的数据,那可以根据某个字段取模到达不重复的效果。
2、不遗漏
如果用上面的方案解决了重复的问题,有1个节点挂掉,需要其他节点接收挂掉节点的任务,这就要求散布式任务调度必须有指挥中心,否则很容易造成重复或遗漏。
上图是tbschedule的架构图,基本满足了散布式任务调度的要求,zookeeper有两个功能,1个是配置数据存储,另外一个是作为调度中心,管理界面直接连接zookeeper获得配置信息,并且修改配置,通过zookeeper通知任务修改配置项。
要求不高的话可以直接拿来用,虽然文档少,但是代码量很少,可以直接通过读代码了解功能。
tbschedule已满足了大多数需求,代码写的也非常优秀,但是有几个地方是可以改进的,
1、前面提到的,1般情况下,我们是不需要多个节点同时工作的,只要有1个节点工作,挂掉其他节点能代替就能够了。由于取数据通常不是性能瓶颈,瓶颈在处理数据,多个节点的目的不过是为了高可用。如果通过sql取模进行分片,sql的性能非常低,走不了索引。如果表数据已做了水平拆分,那可以直接根据数据源切分任务项。
2、tbschedule是把所有任务都处理完才算结束,但是有些场景要求只履行1次,哪怕还有任务要处理,tbschedule需要增加1个配置项;
3、履行时间修改必须在每一个履行周期后才能生效,这个常常在调试的时候出现麻烦,这样做确切是最简单的做法,避免了很多问题,但是如果开发人员要配置任务每分钟履行1次,结果写错了配置成每天履行1次,就完善的落入圈套,等半天也看不到履行,还以为配置错了,重启可以解决;
4、没有负载均衡效果,tbschedule认为每台机器的配置都是1样的,就算配置1样,数据项不1样也容易引发其中1个节点压力特别大。需要根据机器的负载情况、程序的繁忙情况做1个加权平均来做负载。
更多精彩内容,请关注本人公众号
上一篇 [置顶] lua进阶8-- C++读取lua文件里的三维表
下一篇 Log4j终结者(一)――以例子的方式详细介绍Log4j配置文件中代码的含义