前言
分布式任务调度系统应用范围很广,或者说有很多偏后台的分布式系统设计往往可以借鉴分布式调度系统的设计,目前也有很多分布式任务调度系统的开源,比如dkron,XXL-JOB等。这里简单的做一个任务调度系统设计小结,后续可以找时间实现。
业务场景
支持一次性任务
支持广播任务
支持任务编排
支持灵活的时间调度
分布式任务调度系统核心需求
支持水平扩展(系统可以通过水平扩展提高整体系统的处理能力)
运维自动化(扩缩容自动化负载均衡)
高可用(不能有单点风险)
高性能(调度延迟尽量低)
高可靠(支持自动容错,重试)
分布式任务调度系统架构设计
分布式任务调度系统的架构设计围绕上面的核心需求和业务场景进行设计,目前我给出的解决方案。
支持水平扩展(master slave架构,master负责全局的负载均衡,提供租约机制,slave负责具体的调度执行)
运维自动化(当出现自动扩缩容,master负责负载均衡,避免热点问题)
高可用(master 通过etcd进行选主,避免单点,slave不存在单点)
高性能(slave上报延迟等信息给master,由master进行均衡转移,尽量平衡每个slave的负载)
高可靠(租约机制,元数据存元数据存储,减少节点之间的依赖)

master 设计
master的核心是负责全局信息和负载均衡,下发租约,交换心跳信息。master的启动流程:
抢占master锁,保证高可用
等待server 通过心跳联系,交换信息,下发租约
假如出现扩缩容或者负载不均衡,发起负载均衡操作(通知相关server停止部分迁移任务的调度,迁移任务通知新处理的server节点)
server 设计
server 是系统的核心设计,负责具体处理任务调度和执行,3个组件组成:
api(负责对外的api请求接入,支持webui和client接入)
scheduler(调度器负责任务的调度,workflow负责任务之间的编排,corn负责定时任务的调度,scheduler负责优先级的调度)
executor(负责具体的任务执行,支持任务依赖,服务发现,服务通信)
server api 的整体启动流程:
接受任务的api请求,假如不存在任务依赖直接写入到当前server的meta storage,存在依赖并不在当前server节点,写入特殊的一个meta storage目录,其他server可以watch并分别处理。
接受任务后发送到调度器组件开始进行调度
server scheduler的整体设计:
收到api的任务放入cron组件,cron组件需要提供扩展接口,方便新的定时解析
cron组件任务调度时间到后,通过workflow组成任务编排。
任务编排后scheduler根据调度策略进行任务调度,并发送给executor组件
server executor设计:
executor接受task后,需要先进行服务发现,发现上游执行节点(可上游通过client主动上报,也可直接配置,单播可RR执行,广播则需要收集所有节点)
transport 实现和上游的通信协议(可标准协议 http,也可通过client接入用rpc协议接入 默认标准http协议)
executor 负责具体的执行,需要支持任务依赖,不同的任务可并行执行,存在任务依赖的需要根据依赖执行,同时需要支持重试等策略,执行结果存入storage,方便后续查询
容错设计
分布式系统最大的难点就是容错设计,这里可能出现的错误:
server与meta 出现网络问题
server 可能出现fail,stop,recover
server 可能与master 出现网络问题
master出现fail,stop,recover
我们系统设计的解决方案
server与meta 出现网络问题(两种解决方案 master直接回收租约,并发起任务迁移, 2 正常运行,发出告警,master负载均衡处理跳过这个节点)
server 可能出现fail,stop,recover(stop 发起任务迁移,recover 不需要处理,server自己恢复 master发现server下线后可等待一小段时间,假如一直不恢复进行迁移)
server 可能与master 出现网络问题(master发起迁移,server收到迁移信息后,告警并停止任务调度执行)
master出现fail,stop,recover(master重新选主,server收到新的master通知主动联系)