达人专栏 | 还不会用 Apache Dolphinscheduler?大佬用时一个月写出的最全入门教程【三】
作者 | 欧阳涛 招联金融大数据开发工程师
02 Master启动流程
2.10 WorkFlowExecutorThread 里执行 Submit StandByTask 方法
SubmitStandByTask干了5件事情:
- 从ReadyToSubmitTaskQueue中取出TaskInstance。
- (这个TaskInstance是可以重试并且设定为强制成功了的)把task放到completeTaskMap以及taskInstanceMap,并从队列中移除。
- 如果这个task是首次执行的话,就会先从task和ProcessInstance中获取参数(varPool)【这一步的方法是GetPreVarPool】
- 获取这个task依赖结果【这一步的方法是GetDependResultForTask】
- 根据第4步获取的依赖结果,如果依赖结果为失败或者不执行,就从队列中移除,并且放到FailedTaskMap里的。如果依赖结果为成功则将执行SubmitTaskExec方法,同时会放到CompleteTaskMap。至于SubmitTaskExec做了哪些事情将在2.11中说明。
2.11 WorkFlowExecutorThread里执行SubmitTaskExec方法
SumbitTaskExec干了9件事情:
- PackageTaskInstance封装了TaskInstance,就是将TaskInstance和ProcessInstance进行了绑定,并且获取到了MainJar,ResourceList这些信息。
- 根据TaskType获取CommonTaskProcessor,这里采用SPI机制获取。如果想具体了解SPI机制的,可以百度搜索AutoService注解以及ServiceLoad进行详细了解。
- CommonTaskProcessor初始化,也就是将TaskInstance、ProcessInstance、ProcessService、MasterConfig传递给CommonTaskProcessor。
- 通知流程所在的主机,通过netty发送Host和HostUpdateCommand。
- 将CommonTaskProcessor的Action为submit(提交)状态。(这步极为重要)
- 放入到ValidMap,TaskInstanceMap,ActiveTaskProcessorMaps里。
- 将CommonTaskProcessor的Action设置成Run状态的。
- 将task以及ProcessInstance放入到StateWheelExecuteThread进行checkout。
- 如果这个task执行完成就添加到StateEvents队列中。
下一节讲述commonTaskProcessor的submit状态。
2.12 CommonTaskProcessor里执行Submit Task方法
回顾一下上节的第5步,CommonTaskProcessor的Action设置为Submit之后,
去ComonTaskProcessor的父类BaseTaskProcessor找Action方法,在Action方法中有个Switch结构,很明显会进入Submit方法,之后就进入本节所说的SubmitTask方法的了。
SubmitTask在这里干了三件事情:
- ProcessService。SubmitTaskWithRetry可以重复5次(MasterConfig.GetTask CommitInterval)提交task任务,最后在ProcessServiceImpl执行submitTask。
- 将此task的信息插入到TaskGroupQueue数据表中。
- DispatchTask下发任务,将Task任务下发到实现了TaskPriorityQueue接口的TaskPriorityQueueImpl中去。
在ProcessServiceImpl如何执行submitTask将在2.13中说明,同时DispatchTask下发做了那些事情,将在2.15中说明。
2.13 ProcessServiceImpl里执行SubmitTask方法
ProcessServiceImpl是属于Service模块的,SubmitTask主要干了2件事情:
- SubmitTaskInstanceToDB 将任务实例保存到数据库中,当然这里面有数据结构(TaskInstance)的变化,纯属业务的改变的。
- 如果此非结束状态,CreateSubWorkerProcess创建子流程,如果没有子流程,直接跳过2.14的内容。进入2.15。创建子流程做了哪些事情将在2.14中说明。
2.14 ProcessServiceImpl里执行CreateSubWork Process方法
创建子流程需要干6件事情:
- FindWorkProcessMapByParent查找父流程与task绑定的ProcessInstanceMap,是流程实例与Task关系的表。
- SetProcessInstanceMap。设置刚刚查找的ProcessInstanceMap,如果能找到以前跑的ProcessInstanceMap,更新这个ProcessInstanceMap,如果没有找到就创建新的ProcessInstanceMap,并插入到数据库中。
- CreateSubProcessCommand,根据参数,父流程等创建子流程命令的(SubProcessCommand)。
- UpdateSubProcessDefinitionByParent根据父流程更新子流程的定义。
- InitSubInstanceState初始化子实例状态。
- CreateCommand将创建的子流程命令插入数据库中。
这里ProcessInstanceMap并不是jdk包下的map,而是表t_ds_relation_process_instance的数据的。里面存储了父流程实例以及任务的关系的。3到6这些步骤都是crud的业务,里面具体的细节就赘述了。
2.15 CommonTaskProcessor里执行Dispatch Task方法
DispatchTask方法干了三件事情:
- 获取TaskPriorityQueueImpl的bean。
- 将TaskInstance,ProcessInstance封装成TaskPriority。
- 将封装后的TaskPriority放到这bean下的queue中去,这个队列是jdk的PriorityBlockingQueue,是一个具有优先级别的无界阻塞队列。
此时将DispatchTask放进task,那如何消费队列中的task的呢?2.16将说明这个议题。
2.16 TaskPriorityQueueConsumer执行run和dispatchTask方法
TaskPriorityQueueConsumer是一个继承Thread的类。在MasterServer启动之后,根据Spring的特性,TaskPriorityQueueConsumer会创建一个对象由Spring管理。TaskPriority会执行init的方法。线程启动并且设置线程名字Task UpdateConsumerThread。
Run方法中以3(MasterConfig.getMasterDispatch Task ) 次拉取为循环,每次1秒从队列中(BatchDispatch)拉取TaskPriority,如果失败就有重新丢回到这队列中去。
随后对拉取的数据进行DispatchTask方法。
DispatchTask方法中做了三件事情:
- 从TaskPriority中取出context,根据Command,ExecutorType和Workergroup封装成Execution Context。
- 将ExecutionContext交给Executor Dispatcher进行Dispatcher,这将在2.17中说明。
- 如果发送成功,返回result为true。将TaskEvent添加到TaskEventService (addEvents)中,由TaskEventService进行管理的。TaskEventService的说明将在2.19中介绍。
2.17 ExecutorDispatcher里执行Dispatch方法
ExecutorDispatcher这个类就干了三件事情:
- ExecutorDispatcher此类实现了InitializingBean。也就是创建过程中执行了AfterPropertiesSet方法,ExecutorManagers注册了Worker和Client的ExecutorType。
- Dispatch方法中获取到了Worker的ExecutorType,然后进行HostManagar.select。在Select方法中会根据MasterConfig中的Host-selector策略选择机器,默认是Lower-weight。如果读者有自定义的需求,则可以实现HostManager接口的。(Lower-weight如何选择的,就不详细介绍了。因为难度并不大,也就是纯属业务的变化的,有兴趣就可以自行阅读的。)
- 选择完了Host之后,调用ExecutorManager进行execute。这里的EeforeExecute和AfterExecute是没有内容的,如果读者有需求,同样可以在此添加内容的。在2.18中会说明execute的内容。
2.18 NettyExecutorManager执行execute和doExecute方法
ExecutorManager目前就一个实现类,就是NettyExecutorManger。
在init方法中NettyRemotingClient注册了TaskExecuteResponse、TaskExecuteAck和
TaskKillResponse的Processor。这些Processor是用来让Master和Worker进行交互的。
在Executor方法中最核心的方法就是DoExecute。
在DoExecute中NettyRemotingClient根据有效的Host发送Command。如果发送失败了,剔除失败节点,将task重新添加到队列中。
至此,Master就以Command形式发送task信息给Worker,说明一下,此时的Command是Remote包下的Command,与前面的Command没有任何关系的,不要混淆了。Master和Worker的交互过程会在第四章节中讲述。
2.19 TaskEventService执行addEvents方法
先说说TaskEventService创建过程。这是由Spring管理的,然后执行Start方法之后,有两个线程创建出来,一个是TaskEventThread,另外一个是TaskEventHandlerThread。在TaskEventThread会从EventQueue中取出TaskEvent事件进行提交(submitTaskEvent)。而TaskEventHandlerThread会执行EventHandler方法。EventHandler中会从TaskExecuteThreadMap中取出数据来执行executeEvent方法。
那么TaskExecuteThreadMap如何插入数据的呢?答案就是本节所说的addEvents方法。
addEvents方法中会调用TaskExecuteThreadPool中的SubmitTaskEvent方法。而在SubmitTaskEvent方法中最核心的功能就是往TaskExecuteThreadMap放入数据,也就是以ProcessInstanceId为key,TaskExecuteThread为value的map,并且会调用TaskExecuteThrad的addEvent方法,将event放入到events队列中。
至于TaskExecuteThread做了哪些事情将在2.20中说明。
2.20 TaskExecuteThread执行Persist方法
接上文2.19的在TaskExecuteThreadPool中ExecuteEvent方法。
执行TaskExecuteThread中的run方法。在run方法中从events队列中取出TaskEvent,并执行Persist持久化操作的,将task信息保存到数据库中的。
在Persist方法中,重点是Switch结构下的内容。根据DISPATCH,RUNNING,RESULT,执行不同的方法,封装不同的TaskInstance内容保存到数据库中,并发送请求给Worker。
另外构建StateEvent对象,交给WorkerflowExecuteThreadPool进行处理持久化后的StateEvent对象。stateEvent应该如何处理呢?请参考2.22的内容。
2.21 MasterSchedulerService总结
MasterServer的MasterSchedulerService已经基本讲完。回到最开始的MasterServer这部分,发现MasterSchedulerService后面的两个bean没有讲,也就是EventExecuteService以及FailoverExecute Thread.这两个都是线程的,将在2.22和2.23中说明这最后两个bean。
2.22 EventExecuteService线程的run方法
在MasterServer调用Start方法后,EventExeuctor Service的run方法执行过程如下:
- 每100毫秒执行EventHandler方法。
- 每次执行EventHandler方法时,从2.5章节的第3步ProcessInstance ExecCacheManager中取出WorkFlowExecutorThread,通过WorkflowExecuteThreadPool执行ExecuteEvent方法。
- 在ExecuteEvent方法中, 可以发现最核心的方法就是HandlerEvents方法。
- 在HandlerEvents中可以发现,从2.11章节的第9步的StateEvents队列取出StateEvent,然后在通过StateEventHandler方法进行判断的。
- 在WorkflowExecutorThread的stateEventHandler方法中,根据StateEventType的不同,以有6种不同类型的方法去调用,分别为PROCESS_STATE _CHANGE、TASK_STATE_CHANGE、PROCESS_TIMEOUT、TASK_TIMEOUT、TASK_RETRY、PROCESS_BLOCKED。通过不同的type调用不同的方法,如PROCESS_STATE_CHANGE调用ProcessStateChangeHandler方法,这里就不详细讲述各个方法的内容了,其本质上也都是内存数据结构的变化。
P.S.:
- 如果StateEventHandler方法中某一类型成功执行,则从StateEvents队列中移除它了。
- 返回到WorkflowExecuteThreadPool类的ExecuteEvent方法中,执行完第3步之后,会有个回调函数,失败就执行OnFailure方法。成功就执行OnSuccess方法,NotifyProcessChanged通知流程改变中,要么NotifyMyself,要么通知其他流程NotifyProcessChanged的。
2.23 FailoverExecutorThread线程的Run方法
此节为机器故障切换执行的线程,主要干了5件事情。具体执行流程如下:
- Run方法中FailoverService.checkMaster Failover检查是否需要切换的host。
- 如果有host的话,就进入FailoveMaster WithLock方法。在此方法中,从zk中通过分布式锁来进行切换机器,也就是进入FailoverMaster方法。
- 在FailoverMaster中,从ProcessSerivce里(QueryNeedFailover ProcessInstance)查询所需要切换的流程实例(NeedFailover ProcessInstanceList)。
- 接下来,就是通过zk获取有效的WorkerServers.failoverTaskInstance来切换task。在切换task时有三个步骤,分别是:当是Yarnjobs时,则直接杀掉 ; 改变task的状态,也就是从Running到Needfailover ; WorkflowExecutor ThreadPool提交StateEvent。
- 在ProcessService中处理该切换的流程,增加切换流程实例的Command,插入数据库中。
下两章将继续讲述Worker和Master与Worker的交互。
达人专栏 | 还不会用 Apache Dolphinscheduler?大佬用时一个月写出的最全入门教程【三】的更多相关文章
- 【达人专栏】还不会用Apache Dolphinscheduler吗,大佬用时一个月写出的最全入门教学【二】
02 Master启动流程 2.1 MasterServer的启动 在正式开始前,笔者想先鼓励一下大家.我们知道启动Master其实就是启动MasterServer,本质上与其他SpringBoot项 ...
- 我在Apache DolphinScheduler的心路历练
摘要:Apache DolphinScheduler 目前是 Apache 孵化项目,目前正在快速发展中.加入Apache DolphinScheduler社区已一年多,已有 400+ 公司在生产上使 ...
- 金秋十月 - Apache DolphinScheduler 收获 2 位新 Committer
点击上方蓝字关注 Apache DolphinScheduler Apache DolphinScheduler(incubating),简称"DS", 中文名 "海豚调 ...
- 本周六 Apache DolphinScheduler & Doris 将联合线上 Meetup
活动背景 2020年,大数据成为国家基建的一个重要组成,大数据在越来越多的领域展现威力.随着大数据的应用场景越来越多,大家对数据的响应速度和数据加工工作流的方便程度也提出了更高的要求.在这种背景下,相 ...
- Apache DolphinScheduler之最美好的遇见
关于 Apache DolphinScheduler社区 Apache DolphinScheduler(incubator) 于17年在易观数科立项,19年3月开源, 19 年8月进入Apache ...
- 活动回顾|Apache DolphinScheduler x Pulsar 在线 Meetup
关于 Apache DolphinScheduler: " Apache DolphinScheduler(Incubating) 是一个分布式去中心化.易扩展的可视化工作流任务调度系统,致 ...
- Apache DolphinScheduler & Doris 将于本周六联合进行线上 Meetup
01 - 活动介绍 2020年,大数据成为国家基建的一个重要组成,大数据在越来越多的领域展现威力.随着大数据的应用场景越来越多,大家对数据的响应速度和数据加工工作流的方便程度也提出了更高的要求.在这种 ...
- Apache DolphinScheduler 需要的sudo,还可以这么玩,长见识了!
Apache DolphinScheduler(incubator)需要的sudo,还可以这么玩,长见识了! 在新一代大数据任务调度 - Apache DolphinScheduler(以下简称dol ...
- Apache DolphinScheduler新一代分布式工作流任务调度平台实战-上
概述 定义 dolphinscheduler 官网地址 https://dolphinscheduler.apache.org/ dolphinscheduler GitHub地址 https://g ...
随机推荐
- FileAPI
FileAPI ```java File类的常见方法 1.创建. boolean createNewFile(); //创建文件 boolean mkdir();创建文件夹 boolean mkdir ...
- Codeforces Round #773 (Div. 2)
这一场打的非常一般,不过把D想出来了(当然只剩10min没有写出来). A.Hard Way 题意:(很怪的题,我读题读半天)给你一个三角形(端点都在整数点上),问从x轴往上划线(不一定垂直)画不到的 ...
- VSCode 安装以及初步使用教程
老样子先介绍一下VSCode(是什么?干什么?有什么用?好处是什么?等) VisualStudioCode(简称VSCode)是Microsoft开发的代码编辑器,它支持Windows,Linux和m ...
- java中的final与可变类型、不可变类型的关系
如果你对final和不可变类型的概念与区别有疑问的话,可以打开这篇文章.希望我的解答可以帮到您! 1.不可变类型: 什么是可变类型,什么是不可变类型呢? 首先我们看一下下面的这行代码: String ...
- 动态线程池框架 DynamicTp v1.0.6版本发布。还在为Dubbo线程池耗尽烦恼吗?还在为Mq消费积压烦恼吗?
DynamicTp 简介 DynamicTp 是一个基于配置中心实现的轻量级动态线程池管理工具,主要功能可以总结为 动态调参.通知报警.运行监控.三方包线程池管理等几大类. 经过几个版本迭代,目前最新 ...
- 覆盖率检查工具:JaCoCo 食用指南
一:概述 众所周知,软件的代码覆盖率是衡量软件质量的重要指标, 我们今天简单介绍 JaCoCo 的实际使用示例,它是目前在大多数 Java 项目中应用最广泛的覆盖率检测框架 更多资料参考:JaCoCo ...
- Amazon 消息订阅对接
亚马逊的api 谁用谁知道...... 除了坑还是坑 头疼一周整出来,分享给铁汁们 amazon 的订阅思维,我只能说外国人脑回路有点长 下面就讲讲具体流程步骤: 第一步: 参照官方教程:设置通知(A ...
- 20.LVS负载均衡群集—NAT模式实例
LVS负载均衡群集-NAT模式实例 目录 LVS负载均衡群集-NAT模式实例 群集引用概述 群集的含义 问题 解决方法 企业群集分类 群集的三种类型 负载均衡群集(Load Balance Clust ...
- VR技术赋能五大领域,不止高级,更高效!
除了VR游戏.VR影视作品,究竟还有哪些产业领域会应用到VR技术并为生活带来改变呢?今天就帮大家好好梳理一下~ VR赋能交通,不只是高级 最近在网上看到了VR考驾照的新闻,网友都赞叹,现在学车都这么高 ...
- 自己封装的tools.js文件
/* * 生成指定范围的随机整数 * @param lower 下限 * @param upper 上限 * @return 返回指定范围的随机整数,上/下限值均可取 */ function rand ...