极客时间已完结课程限时免费阅读

FAQ第三期 | Apache Beam基础答疑

FAQ第三期 | Apache Beam基础答疑-极客时间

FAQ第三期 | Apache Beam基础答疑

讲述:巴莫

时长09:52大小9.04M

你好,我是蔡元楠。
这里是“FAQ 第三期:Apache Beam 基础答疑”。这一期主要是针对上周结束的模块四——Apache Beam 的基础知识部分进行答疑,并且做了一些补充。
如果你对文章的印象不深了,可以先点击题目返回文章复习。当然,你也可以继续在留言中提出疑问。希望我的解答对你有所帮助。

22 | Apache Beam 的前世今生

在第 22 讲中,我分享了 Apache Beam 的诞生历程。留言中渡码、coder 和 Milittle 都分享了自己了解的技术变迁、技术诞生历史。
而 JohnT3e 则是分享了我在文章中提到的几个论文的具体内容。他分享的论文是非常好的补充材料,也希望你有时间的话可以下载来看一看。我把链接贴在了文章里,你可以直接点击下载浏览。
Morgan 在第 22 讲中提问:Beam 和 Spark 是什么关系?
我的回答是,Spark 可以作为 Beam 的一个底层 Runner 来运行通过 Beam SDK 所编写的数据处理逻辑。相信在读完第 23 讲的内容后,Morgan 会对这个概念有一个更好的认识。

23 | 站在 Google 的肩膀上学习 Beam 编程模型

在第 23 讲中,明翼提出的问题如下:
其实明翼的这些问题本质上还是在问:Beam 在整个数据处理框架中扮演着一个什么样的角色?
首先,为什么不是所有的大数据处理引擎都可以作为底层 Runner 呢?原因是,并不是所有的数据处理引擎都按照 Beam 的编程模型去实现了相应的原生 API。
我以现在国内很火的 Flink 作为底层 Runner 为例子来说一下。
在 Flink 0.10 版本以前,Flink 的原生 API 并不是按照 Beam 所提出的编程模型来写的,所以那个时候,Flink 并不能作为 Beam 的底层 Runner。而在 Flink 0.10 版本以后,Flink 按照 Beam 编程模型的思想重写了 DataStream API。这个时候,如果我们用 Beam SDK 编写完数据处理逻辑就可以直接转换成相应的 Flink 原生支持代码。
当然,明翼说的没错,因为不是直接在原生 Runner 上编写程序,在参数调整上肯定会有所限制。但是,Beam 所提倡的是一个生态圈系统,自然是希望不同的底层数据处理引擎都能有相应的 API 来支持 Beam 的编程模型。
这种做法有它的好处,那就是对于专注于应用层的工程师来说,它解放了我们需要学习不同引擎中原生 API 的限制,也改善了我们需要花时间了解不同处理引擎的弊端。对于专注于开发数据处理引擎的工程师来说,他们可以根据 Beam 编程模型不断优化自身产品。这样会导致更多产品之间的竞争,从而最终对整个行业起到良性的促进作用。
在第 23 讲中,JohnT3e 也给出了他对 Beam 的理解。
我是很赞成 JohnT3e 的说法的。这其实就好比 SQL,我们学习 SQL 是学习它的语法,从而根据实际应用场景来写出相应的 SQL 语句去解决问题。
而相对的,如果觉得底层使用 MySQL 很好,那就是另外的决定了。写出来的 SQL 语句是不会因此改变的。

24 | 为什么 Beam 要如此抽象封装数据?

在第 24 讲中,人唯优的提问如下:
确实,Beam 的 Register 机制和 Spark 里面的 kryo Register 是类似的机制。Beam 也的确为常见的数据格式提供了默认的输入方式的。
但这是不需要重复工作的。基本的数据结构的 coder 在GitHub上可以看到。比如 String,List 之类。

25 | Beam 数据转换操作的抽象方法

在第 25 讲中,我们学习了 Transform 的概念和基本的使用方法,了解了怎样编写 Transform 的编程模型 DoFn 类。不过,sxpujs 认为通用的 DoFn 很别扭。
这个问题我需要说明一下,Spark 的数据转换操作 API 是类似的设计,Spark 的数据操作可以写成这样:
JavaRDD<Integer> lineLengths = lines.map(new Function<String, Integer>() {
public Integer call(String s) { return s.length(); }
});
我不建议你用自己的使用习惯去评判自己不熟悉的、不一样的 API。当你看到这些 API 的设计时,你更应该去想的,是这种设计的目标是什么,又有哪些局限。
比如,在数据处理框架中,Beam 和 Spark 之所以都把数据操作提取出来让用户自定义,是因为它们都要去根据用户的数据操作构建 DAG,用户定义的 DoFn 就成了 DAG 的节点。
实际使用中,往往出现单个数据操作的业务逻辑也非常复杂的情况,它也需要单独的单元测试。这也是为什么 DoFn 类在实际工作中更常用,而 inline 的写法相对少一点的原因。因为每一个 DoFn 你都可以单独拿出来测试,或者在别的 Pipeline 中复用。

26 | Pipeline:Beam 如何抽象多步骤的数据流水线?

在第 26 讲中,espzest 提问如下:
其实我们通过第 24 讲的内容可以知道,PCollection 是具有无序性的,所以最简单的做法 Bundle 在处理完成之后可以直接 append 到结果 PCollection 中。
至于为什么需要重做前面的 Bundle,这其实也是错误处理机制的一个 trade-off 了。Beam 希望尽可能减少 persistence cost,也就是不希望将中间结果保持在某一个 worker 上。
你可以这么想,如果我们想要不重新处理前面的 Bundle,我们必须要将很多中间结果转换成硬盘数据,这样一方面增加很大的时间开销,另一方面因为数据持久化了在具体一台机器上,我们也没有办法再重新动态分配 Bundle 到不同的机器上去了。
接下来,是 cricket1981 的提问:
其实文章中所讲到的随机分配并不是说像分配随机数那样将 Bundle 随机分配出去给 workers,只是说根据 runner 的不同,Bundle 的分配方式也会不一样了,但最终还是还是希望能使并行度最大化。
至于完美并行的背后机制,Beam 会在真正处理数据前先计算优化出执行的一个有向无环图,希望保持并行处理数据的同时,能够减少每个 worker 之间的联系。
就如 cricket1981 所问的那样,Beam 也有类似 Spark 的 persist 方法,BEAM-7131 issue 就有反应这个问题。

28 | 如何设计创建好一个 Beam Pipeline?

在第 28 讲中,Ming 的提问如下:
对此,我的回答是,一个集群有可能同时执行两个 pipeline 的。在实践中,如果你的四个 pipeline 之间如果有逻辑依赖关系,比如一个 pipeline 需要用到另一个 pipeline 的结果的话,我建议你把这些有依赖关系的 pipeline 合并。
如果你的 pipeline 之间是互相独立,你可以有四个独立的二进制程序。这个提问里,Ming 说的集群应该是物理上的机器,这和 pipeline 完全是两个概念。好的集群设计应该能够让你可以自由地提交 pipeline 任务,你不需要去管什么具体集群适合去安排跑你的任务。
JohnT3e 的问题如下:
对于这个问题,我觉得 JohnT3e 可以先退一步,看看这个需求场景到底适不适用于分布式数据处理。
分布式的核心就是并行,也就是说同一批数据集合元素和元素之间是无依赖关系的。如果你的场景对于元素的先后顺序有业务需求,可能可以看看 PubSub,RPC 等是不是更适合。而不是 Beam 的 PCollection。
好了,第三期答疑到这里就结束了。最后,感谢在 Apache Beam 的基础知识模块里积极进行提问的同学们,谢谢你们的提问互动。
@JohnT3e、@渡码、@coder、@morgan、@Milittle、@linuxfans、@常超、@明翼、@ditiki、@朱同学、@Bin 滨、@A_F、@人唯优、@张凯江、@胡墨、@cricket1981、@sxpujs、@W.T、@cricket1981、@espzest、@沈洪彬、@onepieceJT2018、@fy、@Alpha、@TJ、@dancer、@YZJ、@Ming、@蒙开强
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 2

提建议

上一篇
FAQ第二期 | Spark案例实战答疑
下一篇
结束语 | 世间所有的相遇,都是久别重逢
unpreview
 写留言

精选留言(2)

  • JohnT3e
    2019-07-03
    感谢老师的解答
    4
  • Milittle
    2019-07-09
    感谢老师

    作者回复: 🤝