Google Dataflow / Apache Beam Python - 来自PCollection的侧输入会导致性能下降

时间:2018-01-13 17:17:02

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

我们正在使用Python SDK在google dataflow中运行日志文件解析作业。数据分布在几百个日常日志中,我们通过云存储中的文件模式读取这些日志。所有文件的数据量约为5-8 GB(gz文件),总共有5千万到8千万行。

loglines = p | ReadFromText('gs://logfile-location/logs*-20180101')

此外,我们有一个简单的(小)映射csv,它将logfile条目映射到人类可读的文本。有大约400行,5 kb大小。

例如,[param = testing2]的日志文件条目应映射到最终输出中的“客户请求的14天免费产品试用”。

我们在一个简单的beam.Map中使用sideinput这样做:

customerActions = loglines | beam.Map(map_logentries,mappingTable)

其中map_logentries是映射函数,mappingTable是映射表。

但是,这只有在我们通过open()/ read()读取本机python中的映射表时才有效。如果我们通过ReadFromText()使用波束管道并将生成的PCollection作为侧输入传递给Map,就像这样:

mappingTable = p | ReadFromText('gs://side-inputs/category-mapping.csv')    
customerActions = loglines | beam.Map(map_logentries,beam.pvalue.AsIter(mappingTable))

性能完全分解为每秒约2-3项。

现在,我的问题:

  1. 为什么表演会如此糟糕,传递一个错误 PCollection作为侧输入?
  2. 如果不建议使用 PCollections作为侧输入,如何构建如此 需要可以/不应该硬编码的映射的管道 映射函数?
  3. 对我们来说,映射确实经常发生变化,我需要找到让“普通”用户提供它的方法。我们的想法是在云存储中提供映射csv,并通过ReadFromText()将其简单地合并到管道中。在本地阅读它涉及向工人提供映射,因此只有技术团队才能做到这一点。

    我知道侧输入存在缓存问题,但这肯定不适用于5kb输入。

    上面的所有代码都是伪代码来解释问题。任何想法和想法都将受到高度赞赏!

2 个答案:

答案 0 :(得分:3)

您可以使用更高效的侧输入(中小尺寸) beam.pvalue.AsList(mappingTable) 因为AsList导致Beam实现数据,所以你确定你将获得该pcollection的内存列表。

  

用于侧面参数规范---相同的地方   使用AsSingleton和AsIter,但强制实现   这个PCollection作为一个列表。

     

来源:https://beam.apache.org/documentation/sdks/pydoc/2.2.0/apache_beam.pvalue.html?highlight=aslist#apache_beam.pvalue.AsList

答案 1 :(得分:0)

  1. 代码看起来很好。但是,由于mappingTable是映射,因此beam.pvalue.AsDict不适合您的用例吗?

  2. 您的mappingTable足够小,所以侧输入是一个很好的用例。 鉴于mappingTable也是静态的,您可以在start_bundle的{​​{1}}函数中从GCS加载它。有关详细信息,请参阅this帖子的答案。如果将来DoFn变得非常大,您还可以考虑将mappingTablemap_logentries转换为mappingTable个键值对,并使用CoGroupByKey加入它们。