dolphinSechduler 源码解读和部署

编译打包源码,以及遇到的问题

打包完会在dist 目录和对应模块生成jar 包,放入对应部署模块下启动

  1. 版本不对, 全局替换版本
    img

全项目编译

mvn clean install -Prelease '-Dmaven.test.skip=true' '-Dcheckstyle.skip=true' '-Dmaven.javadoc.skip=true'

文档格式化

[ERROR] MavenReportException: Error while generating Javadoc:

mvn spotless:apply

指定项目编译打包 优先使用此方法

mvn clean install -pl  dolphinscheduler-api  '-Dmaven.test.skip=true' '-Dcheckstyle.skip=true' '-Dmaven.javadoc.skip=true'

全部打包

./mvnw clean install -Prelease '-Dmaven.test.skip=true' '-Dcheckstyle.skip=true' '-Dmaven.javadoc.skip=true'

api 文档

http://192.168.8.88:12345/dolphinscheduler/swagger-ui/index.html?language=zh_CN&lang=cn#/a-test-controller/createTokenUsingGET_1

系统架构设计

去中心化的设计

img
DolphinScheduler的去中心化是Master/Worker注册心跳到Zookeeper中,Master基于slot处理各自的Command,通过selector分发任务给worker,实现Master集群和Worker集群无中心。

zookeeper架构图

img

zookeeper角色:

leader
负责进行投票的发起和决议以及更新系统状态

learner
包括跟随者(follower)和观察者(observer),follower用于接受客户端请求并想客户端返回结果,在选主过程中参与投票.Observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度

client
请求发起方

其中每个Server在工作过程中有三种状态:

LOOKING:当前Server不知道leader是谁,正在搜寻
LEADING:当前Server即为选举出来的leader
FOLLOWING:leader已经选举出来,当前Server与之同步

那如何选举server leader呢?

半数通过 ,奇数选举
– 3台机器 挂一台 2>3/2
– 4台机器 挂2台 2!>4/2
具体选举流程:
» 每个Server启动以后都询问其它的Server它要投票给谁。
» 对于其他server的询问,server每次根据自己的状态都回复自己推荐的leader的id和上一次处理事务的zxid(系统启动时每个server都会推荐自己)
» 收到所有Server回复以后,就计算出zxid最大的哪个Server,并将这个Server相关信息设置成下一次要投票的Server。
» 计算这过程中获得票数最多的的sever为获胜者,如果获胜者的票数超过半数,则改server被选为leader。否则,继续这个过程,直到leader被选举出来
» leader就会开始等待server连接
» Follower连接leader,将最大的zxid发送给leader
» Leader根据follower的zxid确定同步点
» 完成同步后通知follower 已经成为uptodate状态
» Follower收到uptodate消息后,又可以重新接受client的请求进行服务了

DS系统架构图

img

架构说明

MasterServer

MasterServer采用分布式无中心设计理念,MasterServer主要负责 DAG 任务切分、任务提交监控,并同时监听其它MasterServer和WorkerServer的健康状态。 MasterServer服务启动时向Zookeeper注册临时节点,通过监听Zookeeper临时节点变化来进行容错处理。 MasterServer基于netty提供监听服务。
在启动流程时候,schedule 扫描流程实例切分任务 放入优先级队列,taskComsumer 去消费分发给worker

该服务内主要包含:
DistributedQuartz分布式调度组件,主要负责定时任务的启停操作,当quartz调起任务后,Master内部会有线程池具体负责处理任务的后续操作;

MasterSchedulerService是一个扫描线程,定时扫描数据库中的t_ds_command表,根据不同的命令类型进行不同的业务操作;

WorkflowExecuteRunnable主要是负责DAG任务切分、任务提交监控、各种不同事件类型的逻辑处理;

TaskExecuteRunnable主要负责任务的处理和持久化,并生成任务事件提交到工作流的事件队列;

EventExecuteService主要负责工作流实例的事件队列的轮询;

StateWheelExecuteThread主要负责工作流和任务超时、任务重试、任务依赖的轮询,并生成对应的工作流或任务事件提交到工作流的事件队列;

FailoverExecuteThread主要负责Master容错和Worker容错的相关逻辑;

WorkerServer

WorkerServer也采用分布式无中心设计理念,WorkerServer主要负责任务的执行和提供日志服务。 WorkerServer服务启动时向Zookeeper注册临时节点,并维持心跳。 WorkerServer基于netty提供监听服务。

该服务包含:
WorkerManagerThread主要负责任务队列的提交,不断从任务队列中领取任务,提交到线程池处理;

TaskExecuteThread主要负责任务执行的流程,根据不同的任务类型进行任务的实际处理;

RetryReportTaskStatusThread主要负责定时轮询向Master汇报任务的状态,直到Master回复状态的ack,避免任务状态丢失;

ZooKeeper

ZooKeeper服务,系统中的MasterServer和WorkerServer节点都通过ZooKeeper来进行集群管理和容错。另外系统还基于ZooKeeper进行事件监听和分布式锁。

AlertServer

提供告警服务,通过告警插件的方式实现丰富的告警手段。

ApiServer

API接口层,主要负责处理前端UI层的请求。该服务统一提供RESTful api向外部提供请求服务。

UI

系统的前端页面,提供系统的各种可视化操作界面。

数据库E-R图设计

用户 队列 数据源

img

项目 - 租户 - 工作流定义 - 定时

img

  1. 一个项目可以有多个工作流定义,每个工作流定义只属于一个项目;
  2. 一个租户可以被多个工作流定义使用,每个工作流定义必须且只能选择一个租户;
  3. 一个工作流定义可以有一个或多个定时的配置;

工作流定义和执行

img

  1. 一个工作流定义对应多个任务定义,通过t_ds_process_task_relation进行关联,关联的key是code + version,当任务的前置节点为空时,对应的pre_task_node和pre_task_version为0;
  2. 一个工作流定义可以有多个工作流实例t_ds_process_instance,一个工作流实例对应一个或多个任务实例t_ds_task_instance;
  3. t_ds_relation_process_instance表存放的数据用于处理流程定义中含有子流程的情况,parent_process_instance_id表示含有子流程的主流程实例id,process_instance_id表示子流程实例的id,parent_task_instance_id表示子流程节点的任务实例id,流程实例表和任务实例表分别对应t_ds_process_instance表和t_ds_task_instance表;

源码解读

启动流程

img

节点如何被执行

api 追踪

  1. api 执行记录到数据库

img

img

img

  1. master 获取执行任务并且分割

一个master MasterSchedulerBootstrap, 这里有两个线程开启:

img
2.1 一个master现成 扫描command 转乘流程实例,如下:

img

2.2 一个workerFollow 线程负责DAG 图拆分,并放入优先级队列 如下:
img

img

img

img

img

img

2.4 TaskPriorityQueueConsumer 失败任务重新处理
img

2.5 通过netty 发送tcp 请求 dispatch 给目标worker
img

img

img

  1. worKer 执行
    img

img

img

img

img

img

img

整个流程看下来我们对他有了一些基本的认识,架构设计,以及各模块间使用netty 进行通信。
各模块通过多线程并发技术,比如优先级先队列 privirtyQueue,conccunrentHashmap 存储信息, 结合设计模式命令模式以及策略模式整合了复杂的组件。
我们可以对界面操作的背后的运行原理,有深层次的理解。使用多线程一方面加速执行,同时还承担了任务的流转,传递消息的角色。

比如说哪个地方模块改动了,需要去哪里重新部署,其他模块要不要部署,都可以有自己的判断。

通过netty 连接各个机器,将机器划分成master 和worker,

通过zookeeper 做注册中心,负责高可用, cap 高可用,高

master 负责任务拆分,下发给worker

worker 负责执行任务

下面是梳理的线程可视化,简化版:

img

资料推荐

zookeeper

dolphinscheduler

posted @ 2024-03-12 09:10  庭有奇树  阅读(115)  评论(0编辑  收藏  举报