如何定期更新Google数据存储区中的少量数据(约250万个条目)?

时间:2018-07-12 03:23:19

标签: google-cloud-datastore

我正在尝试定期执行以下操作(每周说一次):

  • 下载几个公共数据集
  • 将它们合并在一起,从而产生约250万个条目的字典(我正在使用Python)
  • 将结果上传/同步到Cloud Datastore,以便我将其作为项目中运行的其他内容的“参考数据”

同步可能意味着某些条目已更新,其他条目已删除(如果已将其从公共数据集中删除)或创建了新条目。

我使用google-cloud-datastore编写了一个python脚本,但是性能却很糟糕-大约需要10个小时(!)来完成此操作。我在做什么:

  • 遍历数据存储区中的条目
  • 在我的字典中查找它们,并确定是否需要更新/删除(如果字典中不再存在)
  • 写回它们/根据需要删除它们
  • 插入字典中的任何新元素

我已经批处理了请求(使用.put_multi,.delete_multi等)。

我考虑过的一些事情

  • 使用DataFlow。问题在于,每个任务都必须将数据集(我的“字典”)加载到内存中,这既耗时又耗费内存
  • 使用managed import / export。问题是它产生/使用了一些未记录的二进制格式(我想实体序列化为协议缓冲区吗?)
  • 在本地使用多个线程来减轻延迟。问题是google-cloud-datastore库对游标的支持有限(例如,它没有“通过X提前游标”方法),因此我没有办法有效地将DataStore中的实体分成多个块可以由不同的线程处理

如何提高性能?

2 个答案:

答案 0 :(得分:0)

假设您的数据存储区实体仅在同步期间更新,那么您应该能够消除“迭代数据存储区中的条目”步骤,而直接将实体键存储在字典中。然后,如果有必要进行任何更新或删除,只需引用存储在字典中的适当实体键即可。

如果预先预先生成空实体(或键)并以给定间隔存储游标(例如,每100,000个实体),则您可能能够利用多个线程。可能会涉及一些开销,因为您必须构建一个自定义系统来管理和跟踪这些游标。

答案 1 :(得分:0)

如果您使用数据流,则可以先将字典导入到新项目(干净的数据存储数据库)中,而不是加载整个词典,然后在数据流功能中将通过数据流提供给您的密钥加载到clean项目。如果该值是从负载中返回的,则将该值上载到生产项目中(如果不存在),然后从生产项目中删除该值。