计算非常大且不断变化的数据集的最佳实践

时间:2015-10-22 18:11:43

标签: google-app-engine mapreduce google-cloud-datastore app-engine-ndb appengine-pipeline

这不是一个应用程序引擎问题本身......虽然我们的应用程序使用NDB针对数据存储区在App-Engine上运行Python。所以问题是关于在分布式系统中对大型数据集进行工作。

我们有一个不断增长的数据集,我们需要计算统计数据(计数,总和等)。我们有一些系统能够以不同的方式成功地完成这项工作,以便在事情发生变化时对它们进行事务性维护......但是有时候我们想要吹走我们的统计数据并从头开始重新计算它们......或者运行验证程序检查我们一直保持差异的计数/总和

问题是,通常情况下,针对在分布式系统中不断变化的非常大的数据集构建统计信息的最佳实践是什么?

假设我们启动了一个大型MapReduce作业来对一百万个实体上的特定字段进行求和...当该作业运行时,有几个新实体进入,有几个被删除,其他几个求和属性也发生了变化。有哪些最知名/已接受/成功的方法可以确保这些添加/删除/更改成为总和?

2 个答案:

答案 0 :(得分:1)

我这样做的方式是我不会查询所有实例并且每次都对所有实例运行我的操作。我有一个单独的实体组,它在1个属性中处理这些统计信息。每当我创建/更新实例时,我都会相应地更新此属性的值,当我删除实例时,我也会相应地更新该值。

确保所有更新确实更新统计信息实体组的最佳方法是使用每次放置或删除实例时自动运行的hooks

希望有所帮助。

答案 1 :(得分:0)

如果您能够满足以下几个条件:

  • 跟踪每个单独的MapReduce子作业
  • 确定结果将受事务更新影响的各个MapReduce子作业
  • 确保此类受影响的MapReduce子作业不会与影响它们的事务更新同时运行(可能由事务本身确保?)
  • 在事务更新中确定每个干扰的MapReduce子作业,如果子作业已经完成

然后,您可以为已完成的每个干扰子作业生成并应用差异统计更新(可能在完成整个大型MapReduce作业后应用它们?)。没有执行的子作业还不需要这样的差异统计,因为当子作业将在其上执行时,内容将已经更新。

您可能需要单独处理交易更新中的添加,删除和普通更改的干扰。

或者,您可以存储所有MapReduce子作业的部分结果,跟踪哪些部分受事务更新影响(如果有),并在大型Mapreduce作业结束时检查作业运行时是否发生了任何更新。如果是这样,只需重新运行受影响的子作业即可获得更新的部分结果,并将部分结果重新组合成最终结果。重复直到最近部分MapReduce重新运行正在进行时不再发生更新。或多或少rsync样式,用于复制/移动大型实时分区,停机时间最短。

您甚至可以将事务更新中的相关影响信息提供给映射器(稍微更聪明一些),让映射器本身评估对可能受影响的映射的影响并相应地传播信息以重新获得受影响的子作业-run,因为更新进来:)