来自: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]))
)
编辑,回应本·钱伯斯的问题
我们希望防止融合,因为我们有一个集合可以生成更大的集合,我们需要在更大的集合中进行并行化。如果它融合了,我只会在一个较大的集合中找到一个工人。
答案 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]))
)