Skip to content
YangDR edited this page Sep 3, 2018 · 4 revisions

Dataflow/TPL

数据流模型及其 kotlin 实现

摘要: 数据流库提供用于构建数据处理网络的组件和工具,这些组件能帮助用户简单地构建高可靠性的并行应用程序。数据流模型起源于大规模并行计算领域,最初用于构建可靠性分布式计算框架,又称有向无环图(DAG)。随着个人计算机软硬件架构对并行支持性的提升,并行成为提高程序性能的必要操作,因此许多原本只用于分布式计算的设计模式逐步被引入到小型应用程序中。同时,由于交互逻辑复杂性、设备传感器数量和数据量的提升,数据流模型作为事件驱动的并行框架,也随之开始得到应用。本文将从概念、原理、实现和使用方法四个方面介绍数据流模型。Microsoft 数年前就在其 .Net 框架中提供了数据流模型高效而可靠的实现,并随着 .Net Core 一并开源。此实现改编自微软提供的任务并行库/数据流模块,因此文中代码主要使用 kotlin 语言,将使用少量 .Net 平台语言,包括 C# 和 F#。

1. 概念

出于对封装的追求,微软在自家 .Net 平台提供了多种相对复杂的设计模式的实现库,并根据它们的表现形式给它们取了独具一格的名字。其中最为著名的要数 .Net 平台的响应式扩展,即观察者模式的实现库,被微软称为 RX ( Reactive Extensions ) 。2012年 Netflix 针对自身需求,将其移植到 JVM,即红遍大江南北的 rxjava。 而我查到的有关 Dataflow 最早的记载显示Dataflow与2012年5月随 .Net Framework4.5 的任务并行库一起发布,由此可见也许微软认为数据流是比 RX 更强的响应式编程模型。

数据流和 RX 主要的区别在于二者对响应式编程进行建模时选取了不同的研究对象。RX 把一串连续到来的事件组成的事件流序列视作模型操作的基本单元,而数据流关注的则是事件处理网络的拓扑结构。因此 RX 善于处理连续到来的事件相关性较强的情况,典型的如鼠标点击(对单击、双击、三击产生不同的响应),且能通过 C# 特色的Linq 链式调用,像处理列表一样定义事件序列的处理过程。但 RX 包含了许多对细粒度处理流程的优化,以及响应流异常或流完结的操作(著名的冷热事件流机制),因此面对不是一条链的处理过程就必须通过 .publish 方法发布,显得有些力不从心。

因此,数据流舍弃了 RX 模仿列表操作的形式,更加关注任务并行库的用户对并行性的需求,提供了更贴近数据处理任务本质的响应式建模。数据流模型操作的基本单元是数据经过的处理步骤,称为 节点 。通过定义节点并将节点用 链接 相连形成网络 ,用户可以直观的建立对数据整个处理过程的认识,又不必像在 RX 中那样显式指定在何处进行异步调度。因此,也许封装一段 RX 子过程显得没有必要(单链写法已经非常简单)又不够安全(不知道是否需要调度或调度到何处),而在数据流中封装一个子网络就非常自然。

Clone this wiki locally