EasyScheduler调度系统的架构原理及实现思路

发布时间:2020-06-26 13:22:21 作者:d66380022
来源:网络 阅读:4774

系统架构设计

在对调度系统架构说明之前,我们先来认识一下调度系统常用的名词

1.名词解释

DAG: 全称Directed Acyclic Graph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图:
EasyScheduler调度系统的架构原理及实现思路

流程定义:通过拖拽任务节点并建立任务节点的关联所形成的可视化DAG

流程实例:流程实例是流程定义的实例化,可以通过手动启动或定时调度生成

任务实例:任务实例是流程定义中任务节点的实例化,标识着具体的任务执行状态

任务类型: 目前支持有SHELL、SQL、SUB_PROCESS、PROCEDURE、MR、SPARK、PYTHON、DEPENDENT,同时计划支持动态插件扩展,注意:其中子 SUB_PROCESS 也是一个单独的流程定义,是可以单独启动执行的

调度方式: 系统支持基于cron表达式的定时调度和手动调度。命令类型支持:启动工作流、从当前节点开始执行、恢复被容错的工作流、恢复暂停流程、从失败节点开始执行、补数、调度、重跑、暂停、停止、恢复等待线程。其中 恢复被容错的工作流恢复等待线程 两种命令类型是由调度内部控制使用,外部无法调用

定时调度:系统采用 quartz 分布式调度器,并同时支持cron表达式可视化的生成

依赖:系统不单单支持 DAG 简单的前驱和后继节点之间的依赖,同时还提供任务依赖节点,支持流程间的自定义任务依赖

优先级 :支持流程实例和任务实例的优先级,如果流程实例和任务实例的优先级不设置,则默认是先进先出

邮件告警:支持 SQL任务 查询结果邮件发送,流程实例运行结果邮件告警及容错告警通知

失败策略:对于并行运行的任务,如果有任务失败,提供两种失败策略处理方式,继续是指不管并行运行任务的状态,直到流程失败结束。结束是指一旦发现失败任务,则同时Kill掉正在运行的并行任务,流程失败结束

补数:补历史数据,支持区间并行和串行两种补数方式

2.系统架构

2.1 系统架构图

EasyScheduler调度系统的架构原理及实现思路

2.2 架构说明
2.3 架构设计思想
一、去中心化vs中心化
中心化思想

中心化的设计理念比较简单,分布式集群中的节点按照角色分工,大体上分为两种角色:
EasyScheduler调度系统的架构原理及实现思路

中心化思想设计存在的问题:

去中心化

EasyScheduler调度系统的架构原理及实现思路

二、分布式锁实践

EasyScheduler使用ZooKeeper分布式锁来实现同一时刻只有一台Master执行Scheduler,或者只有一台Worker执行任务的提交。

  1. 获取分布式锁的核心流程算法如下

EasyScheduler调度系统的架构原理及实现思路

  1. EasyScheduler中Scheduler线程分布式锁实现流程图:
    EasyScheduler调度系统的架构原理及实现思路
三、线程不足循环等待问题

EasyScheduler调度系统的架构原理及实现思路
上图中MainFlowThread等待SubFlowThread1结束,SubFlowThread1等待SubFlowThread2结束, SubFlowThread2等待SubFlowThread3结束,而SubFlowThread3等待线程池有新线程,则整个DAG流程不能结束,从而其中的线程也不能释放。这样就形成的子父流程循环等待的状态。此时除非启动新的Master来增加线程来打破这样的”僵局”,否则调度集群将不能再使用。

对于启动新Master来打破僵局,似乎有点差强人意,于是我们提出了以下三种方案来降低这种风险:

  1. 计算所有Master的线程总和,然后对每一个DAG需要计算其需要的线程数,也就是在DAG流程执行之前做预计算。因为是多Master线程池,所以总线程数不太可能实时获取。
  2. 对单Master线程池进行判断,如果线程池已经满了,则让线程直接失败。
  3. 增加一种资源不足的Command类型,如果线程池不足,则将主流程挂起。这样线程池就有了新的线程,可以让资源不足挂起的流程重新唤醒执行。

注意:Master Scheduler线程在获取Command的时候是FIFO的方式执行的。

于是我们选择了第三种方式来解决线程不足的问题。

四、容错设计

容错分为服务宕机容错和任务重试,服务宕机容错又分为Master容错和Worker容错两种情况

1. 宕机容错

服务容错设计依赖于ZooKeeper的Watcher机制,实现原理如图:

EasyScheduler调度系统的架构原理及实现思路

其中Master监控其他Master和Worker的目录,如果监听到remove事件,则会根据具体的业务逻辑进行流程实例容错或者任务实例容错。

EasyScheduler调度系统的架构原理及实现思路
ZooKeeper Master容错完成之后则重新由EasyScheduler中Scheduler线程调度,遍历 DAG 找到”正在运行”和“提交成功”的任务,对”正在运行”的任务监控其任务实例的状态,对”提交成功”的任务需要判断Task Queue中是否已经存在,如果存在则同样监控任务实例的状态,如果不存在则重新提交任务实例。

EasyScheduler调度系统的架构原理及实现思路

Master Scheduler线程一旦发现任务实例为” 需要容错”状态,则接管任务并进行重新提交。

注意:由于” 网络抖动”可能会使得节点短时间内失去和ZooKeeper的心跳,从而发生节点的remove事件。对于这种情况,我们使用最简单的方式,那就是节点一旦和ZooKeeper发生超时连接,则直接将Master或Worker服务停掉。

2.任务失败重试

这里首先要区分任务失败重试、流程失败恢复、流程失败重跑的概念:

接下来说正题,我们将工作流中的任务节点分了两种类型。

每一个业务节点都可以配置失败重试的次数,当该任务节点失败,会自动重试,直到成功或者超过配置的重试次数。逻辑节点不支持失败重试。但是逻辑节点里的任务支持重试。

如果工作流中有任务失败达到最大重试次数,工作流就会失败停止,失败的工作流可以手动进行重跑操作或者流程恢复操作

五、任务优先级设计

在早期调度设计中,如果没有优先级设计,采用公平调度设计的话,会遇到先行提交的任务可能会和后继提交的任务同时完成的情况,而不能做到设置流程或者任务的优先级,因此我们对此进行了重新设计,目前我们设计如下:

EasyScheduler调度系统的架构原理及实现思路

    - 任务的优先级也分为5级,依次为HIGHEST、HIGH、MEDIUM、LOW、LOWEST。如下图

EasyScheduler调度系统的架构原理及实现思路

六、Logback和gRPC实现日志访问

EasyScheduler调度系统的架构原理及实现思路

以/流程定义id/流程实例id/任务实例id.log的形式生成日志

总结

本文从调度出发,初步介绍了大数据分布式工作流调度系统--EasyScheduler的架构原理及实现思路。

推荐阅读:
  1. 调度系统的设计原理是什么
  2. Yarn资源调度系统的架构和原理

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

easyscheduler 架构 原理

上一篇:Oracle Database 12c DBA文官手册(第8版)——第5章 开发和实现应用程序(续)

下一篇:PHP用threads实现多线程的方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》