计算GroupBy然后将其传递给Google DataFlow(Python SDK)中的多个转换

时间:2019-04-02 16:04:04

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

我正在使用Apache SDK的Python SDK在Google DataFlow上运行功能提取管道。我需要运行多个转换,所有这些转换都希望项目按键分组。

基于对此question的回答,DataFlow无法自动发现和重用GroupBy之类的重复转换,因此我希望先运行GroupBy,然后将结果PCollection馈送到其他转换(请参见下面的示例代码)

我想知道这是否应该在DataFlow中有效地工作。如果不是,Python SDK中推荐的解决方法是什么?有没有一种有效的方法可以让多个Map或Write转换获取同一GroupBy的结果?就我而言,我观察到DataFlow可以在利用率达到5%的情况下扩展到最大数量的工作人员,并且在遵循此question中所述的GroupBy的步骤上没有取得任何进展。

示例代码。为简单起见,仅显示2个转换。

# Group by key once.
items_by_key = raw_items | GroupByKey()

# Write groupped items to a file.
(items_by_key | FlatMap(format_item) | WriteToText(path))

# Run another transformation over the same group.
features = (items_by_key | Map(extract_features))

2 个答案:

答案 0 :(得分:3)

将单个GroupByKey步骤的输出馈送到多个转换中应该可以正常工作。但是,您可以获得的并行化数量取决于原始GroupByKey步骤中可用的密钥总数。如果任何下游步骤都是高扇出状态,请考虑在这些步骤之后添加一个Reshuffle步骤,这将使Dataflow进一步并行执行。

例如,

pipeline | Create([<list of globs>]) | ParDo(ExpandGlobDoFn()) | Reshuffle() | ParDo(MyreadDoFn()) | Reshuffle() | ParDo(MyProcessDoFn())

在这里

  • ExpandGlobDoFn:扩展输入点并生成文件
  • MyReadDoFn:读取给定的文件
  • MyProcessDoFn:处理从文件读取的元素

我在这里使用了两个Reshuffle(请注意Reshuffle中包含GroupByKey)以允许(1)并行读取给定glob中的文件(2)并行处理给定文件中的元素。

答案 1 :(得分:0)

根据我对enter image description here进行故障排除的经验,在多个转换中重用GroupBy输出可能会使您的管道非常慢。至少这是我对Python的Apache Beam SDK 2.11.0的经验。

常识告诉我,从执行图中的单个GroupBy分支出来应该会使我的管道运行得更快。在120多名工人上运行了23个小时之后,管道无法取得任何重大进展。我尝试添加重排,并在可能的情况下使用组合器并禁用实验性重排服务。

在将管道分成两个管道之前,没有任何帮助。第一个管道计算GroupBy并将其存储在文件中(我需要按原样将其提取到DB)。第二个读取具有GroupBy输出的文件,读取其他输入并运行进一步的转换。结果-所有转换在2小时内成功完成。我认为,如果仅在原始管道中复制GroupBy,则可能会获得相同的结果。

我想知道这是否是DataFlow执行引擎或Python SDK中的错误,还是按预期工作。如果是设计使然,则至少应将其记录在案,并且在提交时不应接受这样的管道,否则应该发出警告。

您可以通过查看“组关键字”步骤中出现的2个分支来发现此问题。看来解决方案是分别为每个分支重新运行GroupBy。 this SO question