|
@@ -5,7 +5,7 @@
|
|
|
**DAG:** 全称Directed Acyclic Graph,简称DAG。工作流中的Task任务以有向无环图的形式组装起来,从入度为零的节点进行拓扑遍历,直到无后继节点为止。举例如下图:
|
|
|
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/dag_examples_cn.jpg" alt="dag示例" width="60%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/dag_examples_cn.jpg" alt="dag示例" width="60%" />
|
|
|
<p align="center">
|
|
|
<em>dag示例</em>
|
|
|
</p>
|
|
@@ -37,7 +37,7 @@
|
|
|
|
|
|
#### 2.1 系统架构图
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/architecture.jpg" alt="系统架构图" width="70%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/architecture.jpg" alt="系统架构图" width="70%" />
|
|
|
<p align="center">
|
|
|
<em>系统架构图</em>
|
|
|
</p>
|
|
@@ -98,7 +98,7 @@
|
|
|
|
|
|
中心化的设计理念比较简单,分布式集群中的节点按照角色分工,大体上分为两种角色:
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/master_slave.png" alt="master-slave角色" width="50%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/master_slave.png" alt="master-slave角色" width="50%" />
|
|
|
</p>
|
|
|
|
|
|
- Master的角色主要负责任务分发并监督Slave的健康状态,可以动态的将任务均衡到Slave上,以致Slave节点不至于“忙死”或”闲死”的状态。
|
|
@@ -115,7 +115,7 @@
|
|
|
|
|
|
###### 去中心化
|
|
|
<p align="center"
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/decentralization.png" alt="去中心化" width="50%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/decentralization.png" alt="去中心化" width="50%" />
|
|
|
</p>
|
|
|
|
|
|
- 在去中心化设计里,通常没有Master/Slave的概念,所有的角色都是一样的,地位是平等的,全球互联网就是一个典型的去中心化的分布式系统,联网的任意节点设备down机,都只会影响很小范围的功能。
|
|
@@ -131,12 +131,12 @@
|
|
|
EasyScheduler使用ZooKeeper分布式锁来实现同一时刻只有一台Master执行Scheduler,或者只有一台Worker执行任务的提交。
|
|
|
1. 获取分布式锁的核心流程算法如下
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/distributed_lock.png" alt="获取分布式锁流程" width="50%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/distributed_lock.png" alt="获取分布式锁流程" width="50%" />
|
|
|
</p>
|
|
|
|
|
|
2. EasyScheduler中Scheduler线程分布式锁实现流程图:
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/distributed_lock_procss.png" alt="获取分布式锁流程" width="50%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/distributed_lock_procss.png" alt="获取分布式锁流程" width="50%" />
|
|
|
</p>
|
|
|
|
|
|
|
|
@@ -146,7 +146,7 @@ EasyScheduler使用ZooKeeper分布式锁来实现同一时刻只有一台Master
|
|
|
- 如果一个大的DAG中嵌套了很多子流程,如下图则会产生“死等”状态:
|
|
|
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/lack_thread.png" alt="线程不足循环等待问题" width="50%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/lack_thread.png" alt="线程不足循环等待问题" width="50%" />
|
|
|
</p>
|
|
|
上图中MainFlowThread等待SubFlowThread1结束,SubFlowThread1等待SubFlowThread2结束, SubFlowThread2等待SubFlowThread3结束,而SubFlowThread3等待线程池有新线程,则整个DAG流程不能结束,从而其中的线程也不能释放。这样就形成的子父流程循环等待的状态。此时除非启动新的Master来增加线程来打破这样的”僵局”,否则调度集群将不能再使用。
|
|
|
|
|
@@ -169,7 +169,7 @@ EasyScheduler使用ZooKeeper分布式锁来实现同一时刻只有一台Master
|
|
|
服务容错设计依赖于ZooKeeper的Watcher机制,实现原理如图:
|
|
|
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/fault-tolerant.png" alt="EasyScheduler容错设计" width="40%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/fault-tolerant.png" alt="EasyScheduler容错设计" width="40%" />
|
|
|
</p>
|
|
|
其中Master监控其他Master和Worker的目录,如果监听到remove事件,则会根据具体的业务逻辑进行流程实例容错或者任务实例容错。
|
|
|
|
|
@@ -178,7 +178,7 @@ EasyScheduler使用ZooKeeper分布式锁来实现同一时刻只有一台Master
|
|
|
- Master容错流程图:
|
|
|
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/fault-tolerant_master.png" alt="Master容错流程图" width="40%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/fault-tolerant_master.png" alt="Master容错流程图" width="40%" />
|
|
|
</p>
|
|
|
ZooKeeper Master容错完成之后则重新由EasyScheduler中Scheduler线程调度,遍历 DAG 找到”正在运行”和“提交成功”的任务,对”正在运行”的任务监控其任务实例的状态,对”提交成功”的任务需要判断Task Queue中是否已经存在,如果存在则同样监控任务实例的状态,如果不存在则重新提交任务实例。
|
|
|
|
|
@@ -187,7 +187,7 @@ ZooKeeper Master容错完成之后则重新由EasyScheduler中Scheduler线程调
|
|
|
- Worker容错流程图:
|
|
|
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/fault-tolerant_worker.png" alt="Worker容错流程图" width="40%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/fault-tolerant_worker.png" alt="Worker容错流程图" width="40%" />
|
|
|
</p>
|
|
|
|
|
|
Master Scheduler线程一旦发现任务实例为” 需要容错”状态,则接管任务并进行重新提交。
|
|
@@ -224,12 +224,12 @@ Master Scheduler线程一旦发现任务实例为” 需要容错”状态,则
|
|
|
|
|
|
- 其中流程定义的优先级是考虑到有些流程需要先于其他流程进行处理,这个可以在流程启动或者定时启动时配置,共有5级,依次为HIGHEST、HIGH、MEDIUM、LOW、LOWEST。如下图
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process_priority.png" alt="流程优先级配置" width="40%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/process_priority.png" alt="流程优先级配置" width="40%" />
|
|
|
</p>
|
|
|
|
|
|
- 任务的优先级也分为5级,依次为HIGHEST、HIGH、MEDIUM、LOW、LOWEST。如下图
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/task_priority.png" alt="任务优先级配置" width="35%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/task_priority.png" alt="任务优先级配置" width="35%" />
|
|
|
</p>
|
|
|
|
|
|
|
|
@@ -242,7 +242,7 @@ Master Scheduler线程一旦发现任务实例为” 需要容错”状态,则
|
|
|
- 介于考虑到尽可能的EasyScheduler的轻量级性,所以选择了gRPC实现远程访问日志信息。
|
|
|
|
|
|
<p align="center">
|
|
|
- <img src="https://analysys.github.io/EasyScheduler/zh_CN/images/grpc.png" alt="grpc远程访问" width="50%" />
|
|
|
+ <img src="https://analysys.github.io/easyscheduler_docs_cn/images/grpc.png" alt="grpc远程访问" width="50%" />
|
|
|
</p>
|
|
|
|
|
|
|