今天要与你分享的主题是“为什么 Beam 要如此抽象封装数据”。
很多人在刚开始接触 Apache Beam 的时候,都会觉得这里面的概念太抽象了。什么 PCollection、PValue、Transform……这都是些什么?尤其是 PCollection,完全和先前的技术知识找不到对应。
确实如此。同样作为数据的容器,PCollection 却并不像 Python/Java 的 List 或者 C++ 的 vector。PCollection 是无序的,Beam 对于 PCollection 中元素的处理顺序不作任何保证。所以,你不可能说“我想处理 PCollection 中的第二个元素”,因为它就没有“第几个”这种概念。
PCollection 也不像 Python/Java 的 Set,或者 C++ 的 unordered_set,PCollection 不一定有固定的边界。所以,你也不能指望去查找一个 PCollection 的大小。在 PCollection 的世界里,也没有“固定大小”这样的概念。
作为程序员,我很讨厌重复造轮子,尤其是新瓶装旧酒。的确,有很多开发者为了体现自己项目的复杂度,故意强行引进了很多概念,让大家都似懂非懂的。这就像是为了体现自己知道茴香豆的“茴”有几种写法一样,故意用另一种写法来体现自己“有文化”。
那么 Apache Beam 引进这么多概念,是不是也是故意强行造轮子呢?答案是否定的。这一讲,我们就要分析 PCollection 为什么会如此设计。
在之前的章节中,我们已经讲到了 Apache Beam 的“爷爷”——FlumeJava 产生的背景。
当时 Google 的工程师们发现 MapReduce 使用起来并没有很方便。如果计算过程都能够分解成 map、shuffle、reduce 步骤的话,MapReduce 是非常能胜任的。
但是,很多现实世界中的问题,往往需要一系列的 map 或 reduce 步骤。这样的数据流水线就需要额外的代码用来协调这些 map 或 reduce 步骤。也需要一些额外的代码去管理分步的 map/reduce 步骤产生的一些中间结果。以至于新的开发者很难理解复杂的流水线。
清楚这样的背景对于理解 Apache Beam 的 PCollection 起源很有帮助。因为,这个项目起源只是为了提供比 MapReduce 更好的开发体验,最终的运算引擎仍然是 MapReduce。
为什么需要 PCollection?
那么,为什么 Beam 需要 PCollection 这样一个全新的抽象数据结构呢?
我们