【问题标题】:Batch Processing in Apache Beam with large overheadApache Beam 中的批处理,开销很大
【发布时间】:2017-07-06 07:31:32
【问题描述】:

我目前正在使用 Python API 开发一个更大的 Apache Beam 管道,该管道从 BigQuery 读取数据并最终将其写回另一个 BigQuery 任务。

其中一个转换需要使用二进制程序来转换数据,为此它需要加载一个包含二进制查找数据的 23GB 文件。因此,启动和运行程序需要大量开销(每次加载/运行大约需要 2 分钟)和 RAM,并且只为一条记录启动它是没有意义的。此外,每次都需要从云存储本地复制 23GB 文件。

二进制文件的工作流程是:

  1. 从云存储中复制 23GB 文件(如果尚未存在)

  2. 将记录保存到文件

  3. 使用 call() 运行二进制文件

  4. 读取二进制输出并返回

程序一次可以处理的记录数量基本上是无限的,所以最好得到一个稍微分散的 Beam 变换,我可以指定一次处理的记录数量(比如 100'000一次),但仍将其分发,因此它可以在多个节点上一次运行 100,000 条记录。

我没有看到 Beam 支持这种行为,可能可以将某些东西作为 KeyedCombineFn 操作一起破解,该操作根据一些拆分标准/键收集记录,然后在 merge_accumulators 步骤中运行二进制文件来处理累积的记录。但这对我来说似乎很hackish。

或者是否可以将 GroupByKey 和处理组作为批处理?这是否保证每个组都被一次处理,或者组可以在幕后被 Beam 拆分?

我还看到 Java API 中有一个 GroupIntoBatches,这听起来像是我需要的,但据我所知,它在 Python SDK 中不可用。

我的两个问题是,在 Apache Beam 中实现此用例的最佳方式(性能方面)是什么,如果没有好的解决方案,是否还有其他一些可能更适合的 Google Cloud 服务可以像Beam --> Other Service --> Beam一样使用?

【问题讨论】:

    标签: python google-cloud-platform google-cloud-dataflow apache-beam


    【解决方案1】:

    不能在后台拆分组,因此使用 GroupByKey 应该可以。事实上,这是一个要求,因为每个单独的元素都必须在一台机器上处理,并且在 GroupByKey 之后,具有给定键的所有值都是同一元素的一部分。

    您可能希望分配随机键。请记住,如果给定键的值太多,可能也很难将所有这些值传递给您的程序——因此您可能还想限制一次传递给程序的值的数量和/或调整分配键的方式。

    分配随机键的一个技巧是在开始包中生成随机数(比如 1 到 1000),然后在进程元素中将其递增并将 1001 包装到 1000。这样可以避免为每个元素生成随机数,并且仍然确保密钥的良好分布。

    您可以为这两个逻辑创建一个 PTransform(将 PCollection<T> 划分为 PCollection<List<T>> 块进行处理),这可能在类似情况下可重用。

    【讨论】:

    • 感谢您的提醒。试一试,它确实可以满足我的需求。
    • 我猜新的Beam.Reshuffle() 可以解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2011-02-16
    相关资源
    最近更新 更多