首页 > 解决方案 > Apache Beam - 我应该了解编写高效数据处理管道的关键概念是什么?

问题描述

我已经使用 Beam 有一段时间了,我想知道编写高效和优化的 Beam 管道的关键概念是什么。

我有一点 Spark 背景,我知道我们可能更喜欢使用 reduceByKey 而不是 groupByKey 来避免洗牌和优化网络流量。

Beam也一样吗?

我会很感激一些提示或材料/最佳实践。

标签: google-cloud-dataflowapache-beam

解决方案


需要考虑的一些项目:

图形设计注意事项:

  • 归档优先;将过滤器操作放在 DAG 中尽可能高的位置)

  • 尽早合并;如果可以选择何时合并,请尽早进行。

  • 如果可能,通过在大滑动窗口之前使用较小的固定窗口来减少大滑动窗口的影响。FixedWindow.of(1m) | 结合 | SlidingWindow.of(6 小时)

  • 大多数跑步者都会支持图融合,这是 99% 的正确选择。但是在大规模扇出变换的情况下,你应该打破融合。

编码员

  • 选择提供良好性能的编码器,例如在 Java 中使用 Proto 或 Avro 编码器,而不是默认的 java 序列化。
  • 高级提示:编码/解码是开销的一大来源。因此,如果您有一个大 blob 但只需要结构化的一部分,您可以选择性地仅解码该部分。

日志记录

  • 避免在每个元素级别使用 Log.info,这很少有价值,并且是许多引发性能相关问题的根本原因。

数据倾斜

  • 了解数据集和热键的含义。用作可空键的字段通常是罪魁祸首...如果需要,请使用并行提示withFanOut
  • 对于一般的键

    • 键太少:不好 - 难以分片工作负载和每个键的顺序会影响性能
    • 键太多:也可能很糟糕 - 开销开始蔓延。
  • 高级关键提示:

    • 有时您可以将键与元素 {key,Window} 的窗口结合起来,以帮助更多地分配工作
    • 不是要求,但如果您有能力并希望进入这一优化级别;瞄准〜O(10K)到O(100K)个键。如果键空间大得多,您可以考虑使用散列在内部将键分开。如果密钥带有日期/时间信息,这将特别有用。在这种情况下,您可以免费“重用”过去不再处于活动状态的处理密钥。

源、汇和外部系统

  • 使用选项标志可以轻松读取压缩文件,但是如果没有 Offset TextIO 则无法分发此任务。如果您有非常大的文件要读取,在启动管道之前解压缩文件可以提供很好的性能提升。还要考虑使用压缩 Avro 等格式。

    • 背压:横梁式滑轨设计为能够快速咀嚼并行工作。他们可以在许多机器上启动许多线程来实现这一目标。这很容易淹没外部系统,尤其是在您进行每个元素的 RPC 调用时。如果无法扩展外部系统,请使用 startBundle / finishBundle 创建批次以帮助提高每秒调用次数

    • 光速,仍然是光速.. :-) 避免使用远离工人的水槽和光源。

指标

  • 利用 Beam 指标来检测您的管道。

推荐阅读