记录一下正在开发的一个任务调度系统,目的是为了解决大数据平台下的任务管理、调度及监控。
定时触发和依赖触发。
系统模块:
JobManager:调度系统的Master,提供RPC服务,接收并处理JobClient/Web提交的所有操作;与元数据通讯,维护Job元数据;负责任务的统一配置维护、触发、调度、监控;
JobMonitor: 监控正在运行的Job状态、监控任务池、监控等待运行的Job;
JobWorker:调度系统的Slave,从任务池中获取Job、负责启动并收集Job的执行状态,维护至元数据;使用Jetty提供任务运行日志访问服务。
JobClient/Web:调度系统客户端类,前端界面提供给用户,用作任务的配置、管理、监控等;
任务元数据:目前使用Mysql,保存Job的配置、依赖关系、运行历史、资源配置、告警配置等;使用Mysql很不靠谱,任务多的时候会成瓶颈,必须迁移至分布式存储,Zookeeper也行;
系统特性:
分布式:容量和负载能力(JobWorker)可线性扩充;
高可用性:拥有主备Master,一旦主Master异常,备Master会接替主Master提供服务;
高容错性:Master重新启动后,会将之前未完成的任务重新调度运行;
完善易用的Web用户界面:用于用户配置、提交、查询、监控任务及任务的依赖关系;
支持任意类型的任务:除了hadoop生态圈的MapReduce、Hive、Pig等,还支持其他任何语言开发的任务,如Java、Shell、Python、Perl、Spark等;
完整的日志记录:收集并记录任务运行过程中产生的标准输出和标准错误,提供Http访问,用户可通过访问任务对应的日志Url来方便的访问任务运行日志;
任务之间的灵活依赖:可将任意一个任务作为自己的父任务进行依赖触发;
灵活多样的告警规则:除了失败告警,也支持任务超时未完成、任务超时未开始等告警规则;
难点:
依赖触发时候,业务日期以及子孙任务的判断,特别是手工运行任务,并且运行所有子孙任务的场景;
元数据的设计和存储:刚开始想借鉴MapReduce的架构,元数据只做持久化,其他全通过RPC,在内存中进行,但复杂度太高。
任务的恢复:服务异常重启之后,想将之前所有的任务恢复到原来的状态。
JobWorker之间的共享存储:暂时将任务程序放在HDFS上,JobWorker在运行任务时候从HDFS获取到本地。
任务超时告警:当一个任务超过某一时间还没开始或者成功结束时触发告警,此类告警放到Quartz中去触发。
JobWorker可以运行在任意机器上,只需要能访问元数据,一些不好迁移的业务程序可以将JobWorker运行在其机器上,添加任务时候需指定资源,这样,在分配任务的时候只会分配到指定的资源上去。
不同的业务需要用不同的用户去执行:将业务类型和用户名绑定。
KILL任务:对于Hadoop和Hive任务,不能仅仅销毁执行进程,需要从日志中解析Hadoop jobid,执行hadoop kill命令。