我正在使用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))
答案 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)
根据我对进行故障排除的经验,在多个转换中重用GroupBy输出可能会使您的管道非常慢。至少这是我对Python的Apache Beam SDK 2.11.0的经验。
常识告诉我,从执行图中的单个GroupBy分支出来应该会使我的管道运行得更快。在120多名工人上运行了23个小时之后,管道无法取得任何重大进展。我尝试添加重排,并在可能的情况下使用组合器并禁用实验性重排服务。
在将管道分成两个管道之前,没有任何帮助。第一个管道计算GroupBy并将其存储在文件中(我需要按原样将其提取到DB)。第二个读取具有GroupBy输出的文件,读取其他输入并运行进一步的转换。结果-所有转换在2小时内成功完成。我认为,如果仅在原始管道中复制GroupBy,则可能会获得相同的结果。
我想知道这是否是DataFlow执行引擎或Python SDK中的错误,还是按预期工作。如果是设计使然,则至少应将其记录在案,并且在提交时不应接受这样的管道,否则应该发出警告。
您可以通过查看“组关键字”步骤中出现的2个分支来发现此问题。看来解决方案是分别为每个分支重新运行GroupBy。 this SO question