Java 连接两大卷的PCollection有性能问题

Java 连接两大卷的PCollection有性能问题,java,google-cloud-dataflow,apache-beam,Java,Google Cloud Dataflow,Apache Beam,使用CoGroupsByKey方法连接两个Pcollection,执行8+百万条记录需要数小时。从另一个stackoverflow帖子中注意到“CoGbkResult有10000多个元素,需要重复(可能很慢)。” 使用此方法改进此性能的任何建议 下面是代码片段 PCollection pc1=。。。; PCollection pc2=。。。; WithKeys withKeyValue= WithKeys.of((TableRow row)->String.format(“%s”,row.get

使用CoGroupsByKey方法连接两个Pcollection,执行8+百万条记录需要数小时。从另一个stackoverflow帖子中注意到“CoGbkResult有10000多个元素,需要重复(可能很慢)。”

使用此方法改进此性能的任何建议

下面是代码片段

PCollection pc1=。。。;
PCollection pc2=。。。;
WithKeys withKeyValue=
WithKeys.of((TableRow row)->String.format(“%s”,row.get(“KEYNAME”))
.withKeyType(TypeDescriptors.strings());
PCollection keyed_pc1=
pc1.应用(“WithKeys”,withKeyValue);
PCollection键控_pc2=
pc2.应用(“WithKeys”,withKeyValue);
//(org.apache.beam.sdk.extensions.joinlibrary.Join类)
PCollection joinedCollection=
Join.innerJoin(keyed_pc1,keyed_pc2);

Apache Beam规范没有定义连接的执行,除了SDK之外,没有其他更快的方法可以自己编写内部连接。因此,这个问题的答案取决于执行连接的是什么,即哪个运行程序。我不知道Flink或Spark的运行程序,所以这个答案将特定于Dataflow运行程序

如果你还没有,看看这篇关于这个的博文。在博客文章中,它描述了可以手动启用的数据流洗牌服务。此服务是比当前默认服务更好的实现,通常会导致更快的执行,尤其是对于连接

要启用数据流洗牌服务,请传入以下内容:

--experiments=shuffle\u mode=service
--区域=

其中允许洗牌的区域为:“美国中部1”、“欧洲西部1”、“欧洲西部4”、“亚洲东北1”

我的理解是,您的join有一个热键:一个包含多个条目的键,其结果条目不适合工作进程的内存。这意味着,当您以后使用它时,可能会导致重新获取数据,这可能会降低性能

innerJoin仍然用于进行连接,因此仅使用该库并不一定会更有效。不过,遍历集合的顺序可能很重要

若一侧有小的pcollection(适合内存),可以使用查找表的方法进行连接。请参阅以供参考


如果你有办法知道哪个键是热门的,你可以在加入之前把它分成几个小的键,但这需要更多的工程方面的工作和一些数据的预先了解。

谢谢你的反馈。是的,此作业正在Dataflow Runner上运行。根据文档,通过传递所提到的参数在我的作业中启用了此洗牌服务,但作业仍在运行一个多小时。通过启用此服务,我看不到性能方面的任何改进。这是我在这项工作中使用的另一种配置,您可以为我提供此分析的进一步输入。选项:setDiskSizeGb(300);选项。setNumWorkers(3);选项。setMaxNumWorkers(50);选项:setWorkerMachineType(“n1-highmem-2”);选项。setRegion(“us-central1”);根据对问题的最初描述,洗牌不是瓶颈。热键是。所以我不认为在你的情况下,洗牌服务和默认的洗牌设备之间会有太大的区别。谢谢你的反馈。我知道热键有很多条目,它不适合工作人员的内存。当前在配置下使用的作业,请告知是否需要增加/减少任何内容以提高性能[options.setDiskSizeGb(300);options.setNumWorkers(3);options.setMaxNumWorkers(50);options.setWorkerMachineType(“n1-highmem-2”);options.setRegion(“us-central1”);]。JoinAsLookup转换对我来说是新的,我将对其进行探索,并向您提供反馈。请分享任何JoinAsLookup示例,非常感谢。参考url很难理解1)您可以尝试使用具有更多可用内存的计算机。不过,这样做的代价更高。2) JoinAsLookup意味着,如果一个表足够小,而另一个表很大,则可以将较小的表转换为边输入,并利用边输入进行连接。此时您将没有CoGBK,但有一个带有侧输入的ParDo。不幸的是,我手边没有榜样。我会看看是否能找到。谢谢你的反馈。目前正在使用SideInput Join,还正在探索如何在加入集合之前将大容量集合拆分为小集合。
--experiments=shuffle_mode=service
--region=<allowed region>