DAG的定义
图数据结构有几个名词解释:
- 顶点(node/vertex)
- 边(edge)
- 度数:由一个顶点出发,有几条边就称该顶点有几度,或者该顶点的度数是几,degree
- 环:至少含有一条边,并且起点和终点都是同一个顶点的路径
- 无环图:是一种不包含环的图
DAG在EM中的应用
拉起应用
如果应用间存在依赖关系,因此EM要拉起的应用可以组成数个有向无环图(有环图是严格禁止的),比如上面的有向无环图可以分解为两个DAG:
- 进程B依赖进程A,进程C依赖进程A,进程D依赖进程B和C
- 进程F依赖于进程E
在应用拉起时,每个要拉起的应用都作为有向无环图的顶点,EM会根据广度优先算法,依次去遍历拉起每个应用,遍历时会判断要拉起的应用入度是否为0,如果为0,表明不依赖其他应用,直接发起调度,如果不为0,表明依赖于其他应用,会等待其他应用的拉起,所有依赖节点都拉起后再进行拉起
如上图的例子,两个DAG分别的拉起顺序为:
- A,{B,C},D
- E,F
实现上,为了加快拉起的速度,会采用线程池+异步Future的方式,首先对于不同的DAG来说不存在依赖关系,因此可以分别拉起,所以会为每个DAG的拉起创建一个StartDAGTask,推入线程池中去执行,得到一个执行结果Future处理DAG的拉起结果。对于一个拉起Task,拉起节点时,也会创建一个StartAppTask,推入线程池中执行,得到一个Future处理该APP的拉起结果。
在开始拉起之前,创建一个Map保存StartAppTask的信息,包括每个Task对应的APP信息和结果,这些结构,所有的Task都能访问,便于处理依赖关系,在执行完成Execute之前必须得到所有的APP拉起结果,表明此次拉起的成功与否
关闭应用
关闭应用和拉起应用一样,但顺序是反的,依据AP规范的要求,假如进程B依赖于进程A,那么在关闭应用时,进程B应当先于进程A关闭,因此进程B可能在关闭时需要保存一些内容,是需要进程A协助的
例如上一节中的两个DAG的关闭顺序应当是:
- D,{B,C},A
- F,E