在应用中使用定时任务进行些数据处理,而放到集群服务里就发现了问题。一是要避免任务被重复执行,二是解决了问题一的情况下一些数据量大的任务只用一台机器处理效率也低。
网上也有挺多类似框架可以做的集群里的定时任务控制,有兴趣可以去查一查。这里我选择的利用Mysql的行级锁(同一时间只有一个线程能操作同一行记录)在集群中对任务进行控制,这样需要建一张任务信息相关的表,恰好应用中也需要,方便查看情况,也便于在一些极端情况下能控制定时任务的执行。
下面说实现:
-一,避免重复执行
可以在任务表中添加标识字段(类似version),在任务执行前可以先执行“update 任务表 set 标识=1 where 标识=0”之类的SQL语句,更新成功则可以看作获取到了执行任务的锁,失败则代表任务已被执行,任务执行完成即可将标识置回未执行状态,如:0。
-二,充分利用集群的优势尽快处理数据
可以在表中设置数据量的大小或任务需处理的次数,与任务执行结果字段(任务结果需记录多个分支任务执行结果,可使用分段字符表示),在标识小于数据量或执行次数时,即可获取执行任务的锁,至于任务所处理数据的范围可在代码中或者其他地方自行控制。(若需同一机器执行多次,可做递归处理。)
任务执行完成时,需利用select for update去获取任务结果,更新并判断执行情况,若全部完成则需重置标识。
有分支任务发生异常中断时,则可递归重试(注意控制重试次数)。
(大体就是,标识控制任务不被重复执行,数据量决定任务分支的多少,任务结果作为整体任务执行情况的判定)
处理方式也比较笨拙了,如有不对和改进的地方,多多指教。