防止Google Dataflow融合的最佳方法?

时间:2017-11-07 16:03:17

标签: google-cloud-dataflow

来自:https://cloud.google.com/dataflow/service/dataflow-service-desc#preventing-fusion

  

您可以在第一个ParDo之后插入GroupByKey并取消组合。 Dataflow服务从不在聚合中融合ParDo操作。

这是我在python中提出的 - 这是合理的/有更简单的方法吗?

def prevent_fuse(collection):
    return (
        collection
        | beam.Map(lambda x: (x, 1))
        | beam.GroupByKey()
        | beam.FlatMap(lambda x: (x[0] for v in x[1]))
        )

编辑,回应本·钱伯斯的问题

我们希望防止融合,因为我们有一个集合可以生成更大的集合,我们需要在更大的集合中进行并行化。如果它融合了,我只会在一个较大的集合中找到一个工人。

3 个答案:

答案 0 :(得分:3)

Apache Beam SDK 2.3.0添加了实验Reshuffle转换,它是@BenChambers提到的Reshuffle.viaRandomKey操作的Python替代方案。您可以使用它代替自定义prevent_fuse代码。

答案 1 :(得分:1)

那应该有用。还有其他方法,但它们部分取决于你想要做什么以及为什么你想要防止融合。请记住,融合是提高管道性能的重要优化。

你能详细说明为什么要阻止融合吗?

答案 2 :(得分:1)

对我原始提案进行小幅调整 - 如果每个项目太大,将失败将失败。您需要将它们强制为多个项目,因此使用常量键不起作用。所以在这里,你可以提供一个key函数,它需要区分对象并且很小,就像哈希一样。

那说,仍然不确定这是最好的方式,还是更简单(beam.Partition?)的工作方式。并且梁对于提供明确的原语会很好。

def prevent_fuse(collection, key=None):
    """
    prevent a dataflow PCol fusing with the next PCol
    supply a key function if the items are too big to use as keys
    """

    key = key or (lambda x: x)

    return (
        collection
        | beam.Map(lambda v: (key(v), v))
        | beam.GroupByKey()
        | beam.FlatMap(lambda kv: (v for v in kv[1]))
        )