@ -799,7 +799,7 @@
< h1 id = "easyscheduler大数据调度系统架构分析" > EasyScheduler大 数 据 调 度 系 统 架 构 分 析 < / h1 >
< h2 id = "架构设计" > 架 构 设 计 < / h2 >
< p > < img src = "../../images/esr_2.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_2.png" alt = "PNG" > < / p >
< blockquote >
< h4 id = "easyscheduler设计围绕四个服务展开,ui、web、server和alert。" > EasyScheduler设 计 围 绕 四 个 服 务 展 开 , UI、 Web、 Server和 Alert。 < / h4 >
< ul >
@ -820,7 +820,7 @@
< h3 id = "1-中心化思想" > 1. 中 心 化 思 想 < / h3 >
< blockquote >
< h4 id = "       中心化的设计理念比较简单,分布式集群中的节点按照角色分工,大体上分为两种角色:" >               中 心 化 的 设 计 理 念 比 较 简 单 , 分 布 式 集 群 中 的 节 点 按 照 角 色 分 工 , 大 体 上 分 为 两 种 角 色 : < / h4 >
< p > < img src = "../../images/esr_3.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_3.png" alt = "PNG" > < / p >
< h4 id = "       master的角色主要负责任务分发并监督slave的健康状态,可以动态的将任务均衡到slave上,以致slave节点不至于忙死或闲死的状态。" >               Master的 角 色 主 要 负 责 任 务 分 发 并 监 督 Slave的 健 康 状 态 , 可 以 动 态 的 将 任 务 均 衡 到 Slave上 , 以 致 Slave节 点 不 至 于 “ 忙 死 ” 或 ” 闲 死 ” 的 状 态 。 < / h4 >
< h4 id = "       worker的角色主要负责任务的执行工作并维护和master的心跳,以便master可以分配任务给slave。" >               Worker的 角 色 主 要 负 责 任 务 的 执 行 工 作 并 维 护 和 Master的 心 跳 , 以 便 Master可 以 分 配 任 务 给 Slave。 < / h4 >
< / blockquote >
@ -831,7 +831,7 @@
< / blockquote >
< h3 id = "3-去中心化" > 3. 去 中 心 化 < / h3 >
< blockquote >
< p > < img src = "../../images/esr_4.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_4.png" alt = "PNG" > < / p >
< h4 id = "       去中心化设计里,通常没有masterslave的概念,所有的角色都是一样的,地位是平等的,全球互联网就是一个典型的去中心化的分布式系统,联网的任意节点设备down机,都只会影响很小范围的功能。" >               去 中 心 化 设 计 里 , 通 常 没 有 Master/Slave的 概 念 , 所 有 的 角 色 都 是 一 样 的 , 地 位 是 平 等 的 , 全 球 互 联 网 就 是 一 个 典 型 的 去 中 心 化 的 分 布 式 系 统 , 联 网 的 任 意 节 点 设 备 down机 , 都 只 会 影 响 很 小 范 围 的 功 能 。 < / h4 >
< h4 id = "       去中心化设计的核心设计在于整个分布式系统中不存在一个区别于其他节点的管理者,因此不存在单点故障问题。但由于不存在-管理者节点所以每个节点都需要跟其他节点通信才得到必须要的机器信息,而分布式系统通信的不可靠行,则大大增加了上述功能的实现难度。" >               去 中 心 化 设 计 的 核 心 设 计 在 于 整 个 分 布 式 系 统 中 不 存 在 一 个 区 别 于 其 他 节 点 的 ” 管 理 者 ” , 因 此 不 存 在 单 点 故 障 问 题 。 但 由 于 不 存 在 ” 管 理 者 ” 节 点 所 以 每 个 节 点 都 需 要 跟 其 他 节 点 通 信 才 得 到 必 须 要 的 机 器 信 息 , 而 分 布 式 系 统 通 信 的 不 可 靠 行 , 则 大 大 增 加 了 上 述 功 能 的 实 现 难 度 。 < / h4 >
< h4 id = "       实际上,真正去中心化的分布式系统并不多见。反而动态中心化分布式系统正在不断涌出。在这种架构下,集群中的管理者是被动态选择出来的,而不是预置的,并且集群在发生故障的时候,集群的节点会自发的举行会议选举新的管理者主持工作。最典型的案例就是zookeeper及go语言实现的etcd。" >               实 际 上 , 真 正 去 中 心 化 的 分 布 式 系 统 并 不 多 见 。 反 而 动 态 中 心 化 分 布 式 系 统 正 在 不 断 涌 出 。 在 这 种 架 构 下 , 集 群 中 的 管 理 者 是 被 动 态 选 择 出 来 的 , 而 不 是 预 置 的 , 并 且 集 群 在 发 生 故 障 的 时 候 , 集 群 的 节 点 会 自 发 的 举 行 " 会 议 " 选 举 新 的 " 管 理 者 " 主 持 工 作 。 最 典 型 的 案 例 就 是 ZooKeeper及 Go语 言 实 现 的 Etcd。 < / h4 >
@ -844,11 +844,11 @@
< h3 id = "easyscheduler使用zookeeper分布式锁来实现同一时刻只有一台master执行scheduler,或者只有一台worker执行任务的提交。" > EasyScheduler使 用 Zookeeper分 布 式 锁 来 实 现 同 一 时 刻 只 有 一 台 Master执 行 Scheduler, 或 者 只 有 一 台 Worker执 行 任 务 的 提 交 。 < / h3 >
< h3 id = "1-获取分布式锁的核心流程算法如下:" > 1. 获 取 分 布 式 锁 的 核 心 流 程 算 法 如 下 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_5.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_5.png" alt = "PNG" > < / p >
< / blockquote >
< h3 id = "2-easyscheduler中scheduler线程分布式锁实现流程图:" > 2. EasyScheduler中 Scheduler线 程 分 布 式 锁 实 现 流 程 图 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_6.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_6.png" alt = "PNG" > < / p >
< / blockquote >
< h2 id = "线程不足循环等待问题" > 线 程 不 足 循 环 等 待 问 题 < / h2 >
< ul >
@ -856,7 +856,7 @@
< / li >
< li > < h3 id = "如果一个大的dag中嵌套了很多子流程,如下图:" > 如 果 一 个 大 的 DAG中 嵌 套 了 很 多 子 流 程 , 如 下 图 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_7.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_7.png" alt = "PNG" > < / p >
< h4 id = "       则会产生死等状态。mainflowthread等待subflowthread1结束,subflowthread1等待subflowthread2结束,subflowthread2等待subflowthread3结束,而subflowthread3等待线程池有新线程,则整个dag流程不能结束,从而其中的线程也不能释放。" >               则 会 产 生 “ 死 等 ” 状 态 。 MainFlowThread等 待 SubFlowThread1结 束 , SubFlowThread1等 待 SubFlowThread2结 束 , SubFlowThread2等 待 SubFlowThread3结 束 , 而 SubFlowThread3等 待 线 程 池 有 新 线 程 , 则 整 个 DAG流 程 不 能 结 束 , 从 而 其 中 的 线 程 也 不 能 释 放 。 < / h4 >
< h4 id = "       这样就形成的子父流程循环等待的状态。此时除非启动新的master来增加线程来打破这样的僵局,否则调度集群将不能再使用。" >               这 样 就 形 成 的 子 父 流 程 循 环 等 待 的 状 态 。 此 时 除 非 启 动 新 的 Master来 增 加 线 程 来 打 破 这 样 的 ” 僵 局 ” , 否 则 调 度 集 群 将 不 能 再 使 用 。 < / h4 >
< / blockquote >
@ -884,13 +884,13 @@
< ul >
< li > < h3 id = "easyscheduler容错设计依赖于zookeeper的watcher机制,实现原理如图:" > EasyScheduler容 错 设 计 依 赖 于 Zookeeper的 Watcher机 制 , 实 现 原 理 如 图 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_8.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_8.png" alt = "PNG" > < / p >
< h3 id = "       master监控其他master和worker的目录,如果监听到remove事件,则会根据具体的业务逻辑进行流程实例容错或者任务实例容错。" >               Master监 控 其 他 Master和 Worker的 目 录 , 如 果 监 听 到 remove事 件 , 则 会 根 据 具 体 的 业 务 逻 辑 进 行 流 程 实 例 容 错 或 者 任 务 实 例 容 错 。 < / h3 >
< / blockquote >
< / li >
< li > < h3 id = "master容错流程图:" > Master容 错 流 程 图 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_9.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_9.png" alt = "PNG" > < / p >
< h3 id = "       zookeeper--master容错完成之后则重新由easyscheduler中scheduler线程调度,遍历-dag-找到正在运行和提交成功的任务,对正在运行的任务监控其任务实例的状态,对提交成功的任务需要判断task-queue中是否已经存在,如果存在则同样监控任务实例的状态,如果不存在则重新提交任务实例。" >               ZooKeeper Master容 错 完 成 之 后 则 重 新 由 EasyScheduler中 Scheduler线 程 调 度 , 遍 历 DAG 找 到 ” 正 在 运 行 ” 和 “ 提 交 成 功 ” 的 任 务 , 对 ” 正 在 运 行 ” 的 任 务 监 控 其 任 务 实 例 的 状 态 , 对 ” 提 交 成 功 ” 的 任 务 需 要 判 断 Task Queue中 是 否 已 经 存 在 , 如 果 存 在 则 同 样 监 控 任 务 实 例 的 状 态 , 如 果 不 存 在 则 重 新 提 交 任 务 实 例 。 < / h3 >
< / blockquote >
< / li >
@ -898,7 +898,7 @@
< ul >
< li > < h3 id = "worker容错流程图:" > Worker容 错 流 程 图 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_10.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_10.png" alt = "PNG" > < / p >
< h3 id = "       master-scheduler线程一旦发现任务实例为-需要容错状态,则接管任务并进行重新提交。" >               Master Scheduler线 程 一 旦 发 现 任 务 实 例 为 ” 需 要 容 错 ” 状 态 , 则 接 管 任 务 并 进 行 重 新 提 交 。 < / h3 >
< / blockquote >
< / li >
@ -921,7 +921,7 @@
< / li >
< li > < h3 id = "介于考虑到尽可能的easyscheduler的轻量级性,所以选择了grpc实现远程访问日志信息。" > 介 于 考 虑 到 尽 可 能 的 EasyScheduler的 轻 量 级 性 , 所 以 选 择 了 gRPC实 现 远 程 访 问 日 志 信 息 。 < / h3 >
< blockquote >
< p > < img src = "../../images/esr_11.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_11.png" alt = "PNG" > < / p >
< / blockquote >
< / li >
< / ul >
@ -932,7 +932,7 @@
< ul >
< li > < h3 id = "fileappender实现如下:" > FileAppender实 现 如 下 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_12.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_12.png" alt = "PNG" > < / p >
< h4 id = "以流程定义id流程实例id任务实例idlog的形式生成日志。" > 以 … /流 程 定 义 id/流 程 实 例 id/任 务 实 例 id.log的 形 式 生 成 日 志 。 < / h4 >
< / blockquote >
< / li >
@ -940,7 +940,7 @@
< ul >
< li > < h3 id = "过滤匹配以taskloginfo开始的线程名称:" > 过 滤 匹 配 以 TaskLogInfo开 始 的 线 程 名 称 : < / h3 >
< blockquote >
< p > < img src = "../../images/esr_13.png" alt = "PNG" > < / p >
< p > < img src = "../ ../../images/esr_13.png" alt = "PNG" > < / p >
< / blockquote >
< / li >
< / ul >
@ -1035,4 +1035,3 @@
< / body >
< / html >