场景
不同集团每个门店销售报表出excel,要求各不相同,需求字段大体相同;
集团对接多个配送,不同配送需要定期对账,分析出费用有差异的订单,生成excel;
概况来说,有一批依赖业务环境的任务,执行需要较多资源,有多节点可以负载执行任务,如何对其协调并高效执行?
单节点多线程,多节点单线程,多节点多线程执行的区别
并发执行面临几个问题。
- 多执行者之间,如何协调一个任务的执行权限?
- 一个执行者异常中断,如何重启任务?
- 如果动态增删执行者,如何有效分配资源?
在这个问题上,有过如下三种模型的思考。
单节点多线程
最简单的方式,就是从一个集群节点中指定固定节点运行任务。
针对第一个问题,
- 一种方式是redis记录任务的占有状态,一旦有线程标记任务占有,则其它线程不得执行;
- 内存中持有一个同步集合,记录任务的占有状态,一旦有线程标记任务占有,则其它线程不得执行;
针对第二个问题,
如果一个线程执行出错,则主动从记录状态的地方将占有移除,任务回到任务池,其它线程可以扫描出来继续执行,如此可以做到任务重启;
针对第三个问题,
这种方式规避了分布式调度的问题,仅在一个节点内部执行,故第三点可以不考虑。
这种方式的瓶颈在于,单点资源是有限的,多任务并发执行时,如果任务有io操作,多线程并不会比单线程快多少;而且频繁的任务执行,会导致此节点业务处理能力基本不可用。
多节点单线程
当任务需要在多节点中执行时,需要引入协调者。
针对第一个问题,
由协调者记录执行权限。
针对第二个问题,
当节点因可感知、或者不可感知时的任何原因中断执行,需要一个协调者参与进来,通过心跳机制检测节点状态与任务执行状态。
- 节点状态检测是为了确保执行节点是否正常存在,以确保合理调度资源;
- 任务执行状态检测是为了确保任务在监控中,避免任务僵死,为任务重启提供可靠性;
针对第三个问题,
动态新增节点,需要主动向协调者注册自己,协调者需要和节点保持心跳,删除节点时,及时从资源池中清理不可达节点。新增节点时,可以将之基于负载均衡策略,合理进行调度。
多节点多线程
多节点多线程和多节点单线程的差别在于线程。任务执行线程资源可以委托协调者托管,协调者可以基于节点负载能力,平均执行时间,当前业务容量负载要求等指标协调线程使用情况。