一种秒级CRON任务的实现原理设计 |
发布: 2013-07-21 22:59 |
cron定时任务在web开发中,实现特定的后台任务处理功能非常有用。 系统级的cron是分钟级的,对有些应用可能不够用。 经过长时间的思路整理,思考出来一种秒级cron的的实现机制。 设计场景, 把秒级cron任务的下次执行时间计算为绝对时间,放在内存hash表中, 每个计算出的时间作为一个hash key,而该时间对应的可能有多个任务, 同一秒的多个任务当作数组或者队列作为hash值存储。 使用libevent的秒级计时器,每秒检测一次任务检测,这个逻辑属于hash表查询, 10w级别,甚至100w级别的内存hash查询不都会有什么延迟时间。 注意这里有个细节,可能导致跳过一秒的问题,对于这种情况,虽然说是一秒检查一次, 实现上需要记录上次执行检查的绝对时间戳,从上次时间戳的下一秒到本次检查的时间戳, 这样才不会遗漏任何任务,即使计时器长时间执行偶尔有跳过一秒。 对于当前检测到所有需要执行的任务,通过线程等异步功能执行,主线程逻辑继续等待下一秒事件。 当然,这里还有一个问题,由于同一时间的任务放在hash表的一个key, 在程序执行过程,会有修改某个key的值的问题,如果值列表的数据结构不合理, 有可能修改慢,或者有锁开销、冲突、死锁等问题,在实现实现的需要特别注意。 最后剩下的问题,就是分布式的机制问题,还需要再考虑整理下,再来补充。 分布式的问题, 每个节点均可接收原始的CRON处理请求 接收到原始的CRON注册请求后, *)可以随机找个节点记录下原始的注册请求,基于不信任客户端的原则, 还需要重新分配一次节点,而不能直接在接收到的节点记录 *)接下来不断循环执行下次任务。 对于任务的可靠性问题, *)可以记录原始CRON注册请求的副本,一个集群中每个原始注册请求信息会记录两份以上 *)对于等待执行的任务,也可以考虑在不同的节点写入两个副本, 以便在某节点故障时副本能够执行而不会丢失任务,或者任务的间隔超过设置的时间间隔 *)这样引入一个问题,需要确认某个任务的主本是否失效,是否在给定的时间执行了 可以通过主本执行,副本延迟检测的机制, 如果检测到已经执行,则修改其标记,以后不再检测, 如果检测到延迟某时间后主本仍旧没有执行,则副本来执行,并设置相应的标记 如果主本在某个时刻恢复了,则需要检测相应的标记。 如果主本不能够恢复,副本需要升级为主本,并再次设置一个副本。 这时,主本恢复时应该是一个空的没有任务的节点,如果有任务,则可能重复任务。 某个节点在离开集群某段时间后,需要自动清空其上的任务。 如果某个节点下线,其上很可能包含原始的注册请求信息,这个丢失的话,问题也比较严重, 需要对这种情况作处理。 如果不能合理的处理节点的下线,以及丢失CRON任务的功能,则无法称之为合格的分布式系统设计。 |
原文: http://qtchina.tk/?q=node/738 |
Powered by zexport
|