Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自PCollection的googledataflow/apachebeam Python端输入降低了性能_Python_Google Cloud Dataflow_Apache Beam - Fatal编程技术网

来自PCollection的googledataflow/apachebeam Python端输入降低了性能

来自PCollection的googledataflow/apachebeam Python端输入降低了性能,python,google-cloud-dataflow,apache-beam,Python,Google Cloud Dataflow,Apache Beam,我们正在使用Python SDK在google数据流中运行日志文件解析作业。数据分布在数百个每日日志中,我们通过文件模式从云存储中读取这些日志。所有文件的数据量约为5-8GB(gz文件),共有5000-8000万行 loglines = p | ReadFromText('gs://logfile-location/logs*-20180101') 此外,我们还有一个简单的(小型)映射csv,它将日志文件条目映射到人类可读的文本。大约有400行,大小为5KB 例如,带有[param=testi

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

loglines = p | ReadFromText('gs://logfile-location/logs*-20180101')
此外,我们还有一个简单的(小型)映射csv,它将日志文件条目映射到人类可读的文本。大约有400行,大小为5KB

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

我们在一个简单的beam.Map中使用sideinput进行此操作,如下所示:

customerActions = loglines | beam.Map(map_logentries,mappingTable)
mappingTable = p | ReadFromText('gs://side-inputs/category-mapping.csv')    
customerActions = loglines | beam.Map(map_logentries,beam.pvalue.AsIter(mappingTable))
其中map_logentries是映射函数,mappingTable是映射表

但是,只有通过open()/read()读取本机python中的映射表时,这才有效。如果我们通过ReadFromText()使用梁管道执行相同操作,并将生成的PCollection作为侧面输入传递到地图,如下所示:

customerActions = loglines | beam.Map(map_logentries,mappingTable)
mappingTable = p | ReadFromText('gs://side-inputs/category-mapping.csv')    
customerActions = loglines | beam.Map(map_logentries,beam.pvalue.AsIter(mappingTable))
性能完全分解为每秒2-3项

现在,我的问题是:

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

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

    以上所有代码都是解释问题的伪代码。如果您对此有任何想法,我们将不胜感激

  • 代码看起来不错。然而,既然
    mappingTable
    是一个映射,那么
    beam.pvalue.AsDict
    不是更适合您的用例吗

  • 您的
    mappingTable
    足够小,因此侧面输入是一个很好的用例。 鉴于
    mappingTable
    也是静态的,您可以从您的
    DoFn
    start\u bundle
    功能中的GCS加载它。有关更多详细信息,请参阅要发布的答案。如果<代码>映射表< /代码>将来变得非常大,您还可以考虑将“<代码> MAPyLogAccess < /COD>和<代码>映射表< /代码>转换为键值对的PcReule>代码>,并使用.

  • 加入它们。
    对于更有效的侧输入(小型到中型),您可以利用
    
    beam.pvalue.AsList(映射表)
    
    因为
    AsList
    导致Beam具体化数据,所以您可以确定您将获得该pcollection的内存列表

    用于侧边参数规范——相同位置 其中使用了Asingleton和AsIter,但强制实现 此PCollection作为列表

    资料来源:


    你说得对,
    AsDict()
    在这里更合适,但不会改变任何性能。我将更深入地查看您链接的帖子并尝试一下,这似乎是一个解决方案(重新使用
    映射表
    )。我将在这里发布我的结果。好的,这基本上完成了我们现在正在做的工作,即在管道之外加载数据,然后在全局范围内重新使用它。唯一的区别是使用GCS API从GCS读取,如果我们坚持这个解决方案,这是一个很好的方法。但是,我认为使用管道本身是更自然的方法。您是否尝试过将
    mappingTable
    map\u logentries
    与CoGroupByKey连接起来?这可能有点过分,但它允许您保持
    ReadFromText('gs://side inputs/category mapping.csv')
    。在我的情况下,这不起作用,因为键(我们在其上执行映射)实际上可以在一行中出现多次(当然是不同的键)。因此,我必须乘以7000万行来重新设置它们的关键帧,然后再次“崩溃”。Marcin Zablocki指出了正确的方向:使用AsList()工作得非常好,我只是不明白为什么AsDict()或AsIter()不行。@SpiXel我对python beam SDK的经验有限。这两个start\u包都是side\u输入,应该是Java中可行的解决方案。但是,可能会多次调用start_bundle,尤其是对于流式管道。如果您尝试加载的数据很慢,这将影响您的性能。您能显示map_logentries的代码吗?在side input中使用AsList()时,您是否观察到相同的行为(性能差)?@MarcinZablocki:刚刚尝试使用AsList(),它的运行速度与我们的解决方法一样快。谢谢你!关于为什么AsList()比AsIter()或AsDict()好得多的任何解释/想法?我已经发布了我的答案谢谢-这解决了我的问题并解释了背后的原因。为什么实现PCollection会带来如此大的性能差异?即使是非物化的PCollection在从磁盘读取时也会被缓冲,因此问题不在于读取效率。也许问题在于它被一遍又一遍地读取,对于
    beam.Map
    接收到的每一批都是一次?如果是这样,这种非缓存行为是由API规定的,还是一个实现细节?