任务调度零碎
序
在有了各种数据统计工作之后,就产生了任务调度需要,咱们须要把工作治理起来对立调度,保障工作之间上下游的依赖关系,监控工作运行状态,异常情况下及时告警,尽可能自动化解决异样,调度零碎高可用,使每天的数据统计工作按时执行实现。
这里咱们采纳了自研的形式来开发任务调度零碎,保证系统的高度可控,以及后续性能扩展性。
当然也有一些开源比拟好用的调度零碎能够间接应用,比方:azkaban、xxl-job 等,能够参考这些开源的架构做调度零碎设计。
零碎指标
整个任务调度零碎须要实现以下性能:
- 工作信息管理
- 依赖关系保护
- 任务调度
- 调度器高可用
- 工作异样告警
- 工作血缘关系治理
架构设计
目前整体架构如上图所示,各个局部的性能如下。
web 端:负责各类工作信息的配置与保护,包含根本信息管理、依赖关系治理、输入输出治理、调度信息配置、报警信息配置等;
mysql:负责保留工作配置信息、任务调度执行打算信息等相干工作信息;
master-active:调度器主节点,次要负责工作的触发、依赖查看、工作公布至 zookeeper、工作报警等模块;
master-standby:调度器主节点备用节点,通过 zookeeper 实现主备辨认与主动切换容灾;
zookeeper:负责主备切换、治理可执行工作信息;
executor:工作执行器,包含工作的解析器、执行器、yarn 资源感知、工作信息管理、工作报警等模块。
这个图形容了工作整体的调度流程,整体流程大抵分为以下几个局部
- master-scheduler[主节点 - 调度解析]
step1:每 60s 拉取一次工作配置信息
step2:获取上线工作列表 + 已在 Quartz 队列的工作
step3:循环工作列表在 scheduler 中高低线定时工作
step4:触发工作
- master-quartzJob[主节点 - 执行打算解析]
step5:获取执行工作信息
step6:生成与更新执行工作信息记录至 mysql 表
- master-taskWatcher[主节点 - 执行打算观察者]
step7:获取待执行工作信息
step8:依照日期分组获取期待执行的工作信息
step9:查看 zk 节点是否存在,创立筹备执行节点 /schedule/ready\_{date}
step10:查看是否反对并发与【依赖】工作是否实现,在 zk 上创立工作节点 /schedule/ready\_{date}/{job\_id},并在节点上保留要害调度信息
- executor-readyWatcher[执行器 - 待执行工作观察者]
step11:每 30s 从 zk 上获取 /schedule/ 下的节点信息
step12:循环 ready 节点的信息创立对应 running 节点 /schedule/running\_{date}
step13:查看执行中的工作是否超过单节点工作执行数量下限
step14:获取可执行工作数量以下的 ready 工作信息,循环判断【资源】是否容许容许。容许运行则依据工作类型通过 python 脚本生成可执行命令
step15:更新工作状态并开启线程执行工作
- executor-jobExecutor[执行器 - 工作执行]
step16:开启线程执行运行脚本
step17:获取执行线程 info、error 输出流,依据运行后果判断是否胜利,是否须要重试执行,并更新执行状态
其中绝对独立的 2 个模块:
- executor-python 解析器
依据工作类型,调用不同的 python 解析脚本,生成对应工作可执行命令文件,以供调度器理论运行时调度应用。因为该局部频繁的改变各类参数,所以采纳 python 脚本生成的形式。
- executor-yarn 资源管制
通过 yarn 的 api 接口获取到集群以后资源状况,管制执行器是否能向以后集群持续提交工作
整体操作 zookeeper 局部采纳了 Curator 分布式锁。
优化降级
在我的项目上线一段时间之后,后续咱们陆续做了一下性能优化:
- 工作通过 hash 负载平衡到各个 executor 进行执行
- 工作反对并行执行
- 工作反对配置重试次数
- 提早告警
- 工作变动告诉上游工作
- 反对自定义运行参数
- 工作资源使用率等衰弱状况监控统计
- 扩大反对更多的工作类型
至此整个任务调度零碎临时开发实现,初步完了任务调度零碎所须要的外围性能。
上一篇《数据系统架构 -7. 数据智能》