![](/img/trans.png)
[英]Google Cloud Dataflow ETL (Datastore -> Transform -> BigQuery)
[英]Parallel and bulk process datastore elements in google cloud dataflow
问题:
我的数据存储区项目中有2M +用户数据的列表。 我想向所有用户发送每周通讯。 邮件API每个API调用最多接受50个电子邮件地址。
先前的解决方案:
使用应用程序引擎后端和简单的数据存储区查询一次性处理所有记录。 但是发生的事情是,有时我会收到内存溢出严重错误日志,并且过程重新开始。 因此,某些用户多次收到同一封电子邮件。 所以我转到了数据流。
当前解决方案:
我使用FlatMap函数将每个电子邮件ID发送给一个函数,然后分别向每个用户发送电子邮件。
def process_datastore(project, pipeline_options):
p = beam.Pipeline(options=pipeline_options)
query = make_query()
entities = (p | 'read from datastore' >> ReadFromDatastore(project, query))
entities | beam.FlatMap(lambda entity: sendMail([entity.properties.get('emailID', "")]))
return p.run()
借助云数据流,我确保每个用户仅收到一次邮件,并且不会错过任何人。 没有内存错误。
但是此当前过程需要7个小时才能完成运行。 我尝试用ParDo替换FlatMap,并假设ParDo将并行化该过程。 但是,即使那样也需要相同的时间。
题:
如何将电子邮件ID分成50个一组,以便有效地使用邮件API调用?
如何使过程并行化,以使花费的时间少于一个小时?
您可以使用查询游标将用户分成50个批次,并在推送队列或deferred
任务中进行实际的批次处理(发送电子邮件)。 这将是仅GAE的解决方案,没有云数据流,恕我直言要简单得多。
您可以在Google Appengine中找到这样的处理示例:任务队列性能 ( 也要考虑答案)。 该解决方案使用了deferred
库,但是使用推送队列任务几乎是微不足道的。
答案涉及到并行性方面,您可能希望限制它以降低成本。
您还可以将批处理本身拆分为任务,以获得无限扩展的解决方案(任意数量的收件人,而不会遇到内存不足或超过期限的失败),任务可以重新占用其自身以继续从中断的地方继续工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.