我们要讨论的最后一个系统是 Apache Beam(图 10-33)。Beam 与本章中的大多数其他系统不同之处在于,它主要是一个编程模型、API 和可移植性层,而不是具有执行引擎的完整堆栈。但这正是重点所在:正如 SQL 作为声明式数据处理的通用语言,Beam 旨在成为编程式数据处理的通用语言。让我们来探讨一下。
图 10-33. 时间轴:Beam
具体来说,Beam 由多个组件组成:
-
一个统一的批处理加流式编程模型,继承自其起源地 Cloud Dataflow,我们在本书的大部分内容中讨论了其细节。该模型独立于任何语言实现或运行时系统。您可以将其视为 Beam 对 SQL 的关系代数的等价物。
-
一组SDKs(软件开发工具包),实现了该模型,允许以特定语言的习惯方式表达流水线。Beam 目前提供了 Java、Python 和 Go 的 SDKs。您可以将这些视为 Beam 对 SQL 语言的编程等价物。
-
一组DSLs(领域特定语言),建立在 SDKs 之上,提供专门的接口,以独特的方式捕捉模型的部分内容。而 SDKs 需要展示模型的所有方面,DSLs 只能暴露那些对特定领域有意义的部分。Beam 目前提供了一个名为 Scio 的 Scala DSL 和一个 SQL DSL,两者都是建立在现有的 Java SDK 之上的。
-
一组可以执行 Beam 流水线的运行器。运行器以 Beam SDK 术语描述的逻辑流水线,并尽可能高效地将其转换为物理流水线,然后执行。目前存在的 Beam 运行器包括 Apex、Flink、Spark 和 Google Cloud Dataflow。用 SQL 术语来说,您可以将这些运行器视为 Beam 对各种 SQL 数据库实现的等价物,如 Postgres、MySQL、Oracle 等。
Beam 的核心愿景建立在其作为可移植性层的价值上,而在这个领域中更具吸引力的特性之一是其计划支持完全跨语言的可移植性。尽管尚未完全完成(但即将到来),计划是让 Beam 在 SDK 和运行器之间提供足够高效的抽象层,以实现完全的跨产品 SDK × runner 匹配。在这样的世界中,使用 JavaScript SDK 编写的流水线可以在 Haskell 运行器上无缝执行,即使 Haskell 运行器本身没有本地执行 JavaScript 代码的能力。
作为一个抽象层,Beam 相对于其 runners 的定位对于确保 Beam 实际为社区带来价值至关重要,而不是引入一个不必要的抽象层。关键在于,Beam 的目标是永远不只是其 runners 中发现的特性的交集(最低公共分母)或并集(厨房水槽)。相反,它的目标是仅包括整个数据处理社区中最好的想法。这允许在两个维度上进行创新:
Beam 中的创新
图 10-34。强大和模块化的 I/O
Beam 可能会包括并非所有 runners 最初都支持的运行时特性的 API 支持。这没关系。随着时间的推移,我们期望许多 runners 将在未来版本中纳入这些特性;那些不这样做的将成为需要这些特性的用例的不太吸引人的 runner 选择。
这里的一个例子是 Beam 的 SplittableDoFn API,用于编写可组合的可伸缩源(由 Eugene Kirpichov 在他的文章“在 Apache Beam 中使用 Splittable DoFn 编写强大和模块化的 I/O 连接器”中描述)。它既独特又非常强大,但对于一些更具创新性的部分,比如动态工作重新平衡,目前还没有得到所有 runners 的广泛支持。然而,考虑到这些特性带来的价值,我们预计随着时间的推移,情况将会改变。
runners 中的创新
Runners 可能会引入运行时特性,而 Beam 最初并不提供 API 支持。这没关系。随着时间的推移,已经证明其有用性的运行时特性将被纳入 Beam 的 API 支持中。
这里的一个例子是 Flink 中的状态快照机制,或者之前我们讨论过的 savepoints。Flink 仍然是唯一公开可用的流处理系统,以这种方式支持快照,但 Beam 中有一个提案提供围绕快照的 API,因为我们认为随着时间的推移,管道的优雅演进是一个重要的特性,将在整个行业中具有价值。如果我们今天神奇地推出这样的 API,Flink 将是唯一支持它的运行时系统。但同样,这没关系。这里的重点是,随着这些特性的价值变得清晰,整个行业将随着时间的推移开始赶上。¹²这对每个人都更好。
通过鼓励 Beam 本身以及 runners 内的创新,我们希望随着时间的推移以更快的速度推动整个行业的能力,而不会在这一过程中接受妥协。通过实现跨运行时执行引擎的可移植性的承诺,我们希望建立 Beam 作为表达编程数据处理流水线的通用语言,类似于 SQL 如今作为声明式数据处理的通用货币存在。这是一个雄心勃勃的目标,截至目前,我们离完全实现它还有一段距离,但我们迄今为止也走了很长一段路。