DAG 任务调度与 go-streams 结合的应用实践

01 说在前面 自“双碳”政策提出以来,开务数据库(原:云溪数据库)聚焦“数字能源”领域,为用户打造数字能源管理平台,旨在提升综合能源和碳资产管理能力。通过数字流打通能源流创造价值流,以数据为核心的生产要素,推进风、电、光伏等多种能源流与由数据构成的信息流深度融合。
数字能源管理平台不仅需要处理海量数据且并发度极高,通过能源设施的接入,依托大数据及人工智能,打通物理世界与数字世界,联动信息流与能量流,打破能源品类边界,提升设施效用。
为提高实际业务中计算资源使用效率,优化性能指标,开务重点优化了任务调度策略。DAG(Directed Acyclic Graph) 调度是各行各业都会普遍存在的问题,尤其在遇到任务复杂且相互间存在依赖的情况。那么今天我们将为大家介绍 DAG 任务调度,并分享开务是如何实现将 DAG 与 go-streams 的结合并进行实践应用。
02 什么是 DAG? 【DAG 任务调度与 go-streams 结合的应用实践】DAG,有向无环图(Directed Acycling Graph):指图中没有回路(环)的有向图,是一类具有代表性的图,主要用于研究工程项目的工序、进度等问题。
一个工程(Project)都可分为若干个活动(Active)的子工程(或工序),各个子工程受到一定的条件约束:某个子工程必须开始于另一个子工程完成之后;整个工程有一个开始点(起点)和一个终点。
对工程活动加以抽象后,图的顶点表示活动,有向边表示活动之间的优先关系,这样的有向图称为用顶点表示活动的网(Activity On Vertex Network ,AOV 网)。
通过 DAG 可以帮助大家:预测工程能否顺利完成、找到影响工程的关键活动、估算整个工程完成所必须的最短时间等。由此可见,DAG 具有很高的实用价值。
03 什么是 go-streams? go-streams 是用于 Go 的轻量级流处理库,提供了一种简单简洁的 DSL 来构建数据管道。
DAG 任务调度与 go-streams 结合的应用实践
文章图片

在实际计算中,管道(数据管道)是一组串联连接的数据处理元件,其中一个元件的输出是下一个的输入。管道的元素通常以并行或时间切片的方式执行,并需要在元素之间插入一定量的缓冲存储器。
在解决实际问题的建模过程中,一般是将任务分为多个依次执行的处理步骤,步骤间通过传输数据相关联:一个步骤的输出是下一个步骤的输入,上游生产数据,下游消费数据。
go-streams 抽象出来 Flow 接口,官方实现了常见的操作包括:Map、FlatMap、Filter、PassThrough、Split、FanOut、Merge、Throttler、SlidingWindow、TumblingWindow 等。
04 什么是任务调度? 任务调度,顾名思义是指可以把"任务"这个原子单位按照自组织方式进行调度,任务间可能互相依赖,经过复杂的编排后即可形成一个 Workflow 。
我们希望这个 Workflow 按照事先制定的调度方式去执行每个原子 Task ,如下图所示:我们希望先并发运行 Task A 和 Task C,Task A 执行完后串联运行 Task B,并发等待 Task B 和 Task C 都结束后运行 Task D,这样就完成了一个典型的任务调度 Workflow。
DAG 任务调度与 go-streams 结合的应用实践
文章图片

前面提到了 DAG 的图结构,顶点元素称为 Vertex,顶点间的连线称为边 Edge。一般带箭头关系的称为有向图,箭头关系能形成环状的称为有环图,反之称为无环图。显然运用在任务调度 Workflow 中, DAG 有向无环图是最合适的。
05 任务调度与 go-streams 结合 图的存储结构有:邻接矩阵、邻接表和十字链表。我们选择通过 Map 实现的十字链表作为有向无环图的数据结构。这样可以用时间复杂度查找出的邻边,并且代码可读性较高。
有向无环图的节点分为源节点、流节点和目标节点。源节点对应 go-streams 的源,文件可以是 Kafka、Redis、Txt 等;流节点就是 go-streams 的数据处理管道;目标节点对应 go-streams 的输出目标。
DAG 任务调度会根据图中邻接的入边和出边的数量,自动进行 Merge 和 Fanout。即如果某一个节点邻接的入边的数量大于 1,那么该节点在执行节点任务之前,会先进行 Merge;如果某一个节点邻接的出边的数量大于 1,那么该节点在执行节点任务之后,会进行 Fanout。
如图所示:1 和 2 是两个源,经过 3 和 4 分别用加法处理 1 和 2 两个源;然后 3 和 4 调用 Merge 操作,合成一个流;接着进行 6 的 Fanout 操作,生成两个相同的流,分别流入7 和 8;最终经过 7 和 8 的数字类型转成字符串,分别写入到 out1.txt 和 out2.txt 文件中。
DAG 任务调度与 go-streams 结合的应用实践
文章图片

06 总结回顾 通过 DAG 任务调度与 go-streams 的结合,实现基于 go-streams 并发执行任务,充分利用多核 CPU,提高整个任务流的执行速度。
数字能源管理平台涉及繁杂的有流计算规则,同时包括基于规则的 DSL。通过 DAG 任务调度模块,不仅可以将规则进行统一的任务调度提升效率,同时 DAG 任务调度很大程度上对代码进行简洁优化,降低冗余度,便于后续开发维护。

    推荐阅读