我们正在使用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项。
现在,我的问题:
对我们来说,映射确实经常发生变化,我需要找到让“普通”用户提供它的方法。我们的想法是在云存储中提供映射csv,并通过ReadFromText()将其简单地合并到管道中。在本地阅读它涉及向工人提供映射,因此只有技术团队才能做到这一点。
我知道侧输入存在缓存问题,但这肯定不适用于5kb输入。
上面的所有代码都是伪代码来解释问题。任何想法和想法都将受到高度赞赏!
答案 0 :(得分:3)
您可以使用更高效的侧输入(中小尺寸)
beam.pvalue.AsList(mappingTable)
因为AsList
导致Beam实现数据,所以你确定你将获得该pcollection的内存列表。
用于侧面参数规范---相同的地方 使用AsSingleton和AsIter,但强制实现 这个PCollection作为一个列表。
答案 1 :(得分:0)
代码看起来很好。但是,由于mappingTable
是映射,因此beam.pvalue.AsDict
不适合您的用例吗?
您的mappingTable
足够小,所以侧输入是一个很好的用例。
鉴于mappingTable
也是静态的,您可以在start_bundle
的{{1}}函数中从GCS加载它。有关详细信息,请参阅this帖子的答案。如果将来DoFn
变得非常大,您还可以考虑将mappingTable
和map_logentries
转换为mappingTable
个键值对,并使用CoGroupByKey
加入它们。