dolphinscheduler v2.0.1 master和worker执行流程分析(二)

process的事件驱动实现原理

再讲整个流程之前,必须先搞明白master如何管理process整个生命周期的所有操作。

process内有会有多个task,task会按照dag从上往下执行,整个执行时间会很长,如果为每个process开启单独线程同步执行,管理process的所有操作,这样会导致并发数受限,处理能力下降,浪费资源。

 海豚则引入了事件,用于驱动线程执行。下面讲解原理(上图中事件驱动相关已经框起来了)

WorkflowExecuteThread:Master每处理一个process,都会对应实例化一个线程类。内部重要组成有(黄色框)

        StateEventQueue队列:用于接收存放事件

        handleEvent()方法:用户处理事件,主要有PROCESS_STATE_CHANGE,TASK_STATE_CHANGE等事件

processInstanceExecMaps:存放master端所有的WorkflowExecuteThread,key为prcocessInstacneId(红色框)

TaskResponseServiceStateEventResponseService:主要有两个操作,1.接收master端所有事件;2.内置定时轮询执行线程,将事件分发到相应process对应的WorkflowExecuteThread线程StateEventQueue队列中(蓝色框)

EventExecuteService:扫描、过滤所有processInstanceExecMaps内事件大于0的WorkflowExecuteThread线程,并内置提交WorkflowExecuteThread的线程池,处理事件(绿色框)

根据以上核心组成,来梳理下每个WorkflowExecuteThread线程是如何被事件驱动的。

  1. master为每个process创建WorkflowExecuteThread,并缓存到processInstanceExecMaps中
  2. TaskResponseService和StateEventResponseService将接收到的事件分发到WorkflowExecuteThread的StateEventQueue队列中
  3. EventExecuteService则不断地提交执行事件大于0的WorkflowExecuteThread,执行handleEvent()方法
  4. 不断重复2、3,实现WorkflowExecuteThread事件驱动

Bug案例分析一

2.0.1-release分支WorkflowExecuteThread类1150行,调用 this.processStateChangeHandler(stateEvent);  这个操作是直接触发process级别状态变更操作,如果process是finished(success,failed等),那么WorkflowExecuteThread会调用endProcess正常结束,但是processInstanceExecMaps中依旧存放着WorkflowExecuteThread引用,并且因为该WorkflowExecuteThread不会再有任何事件,EventExecuteService不能提交而永远不能释放,造成内存泄漏。此外,EventExecuteService在监控到process结束后,独有的notifyProcessChanged(通知process)操作也不能被执行。

bug解决:

修改为 this.stateEvents.add(stateEvent); 添加到事件队列,等待EventExecuteService提交。

二开建议:

所有的状态变更,都要添加到事件队列。

相关issue:

https://github.com/apache/dolphinscheduler/issues/9065

Bug案例分析二

EventExecuteService的作用是扫描,过滤提交执行WorkflowExecuteThread线程,因为是通过定时轮询执行,所以很有可能在相邻两次时间扫描到相同WorkflowExecuteThread,为了避免多次提交,所以每次轮询会把已经提交的WorkflowExecuteThread存到eventHandlerMap中。这里没有问题,但是需要清醒的认识到,一旦放进去,就表示处理中,也就是以后都不会被提交

接下来,分析Bug的产生。

FutureCallback处理结束后会有两个结果,onSuccess和onFailure

先看onFailure,里面什么也没处理,对,没有任何处理,那么WorkflowExecuteThread将永远被标记为处理中,即使有事件被添加,事件驱动也失效,那么1.process状态将永远不变,2.内存将永远不能释放

 在看onSuccess,同理,如果在 eventHandlerMap.remove(workflowExecuteThread.getKey()); 之前发生异常,那么WorkflowExecuteThread将永远被标记为处理中,即使有事件被添加,事件驱动也失效,那么1.process状态将永远不变,2.内存将永远不能释放

bug解决:

在onFailure添加 eventHandlerMap.remove(workflowExecuteThread.getKey())

在onSuccess添加 try catch

相关issue:

https://github.com/apache/dolphinscheduler/issues/8810
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值