【问题标题】:Best practices for counting very large and changing datasets计算非常大且不断变化的数据集的最佳实践
【发布时间】:2015-10-22 18:11:43
【问题描述】:

这本身不是一个应用程序引擎问题......尽管我们的应用程序在应用程序引擎上的 Python 中运行,使用 NDB 针对数据存储。所以问题是关于在分布式系统中处理大型数据集。

我们有一个不断增长的数据集,我们需要根据(计数、总和等)计算统计数据。我们有适当的系统以不同的方式成功地做到这一点,以便在事情发生变化时以事务方式维护它们……但是在某些情况下,我们想要删除我们的统计数据并从头开始重新计算它们……或者运行验证例程检查我们一直保持差异的计数/总和

问题是,一般来说,针对分布式系统中不断变化的超大型数据集构建统计数据的最佳实践是什么?

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

【问题讨论】:

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


    【解决方案1】:

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

    确保任何更新都会更新统计实体组的最佳方法是使用hooks,它会在您每次放置或删除实例时自动运行。

    希望对您有所帮助。

    【讨论】:

    • 是的,我们也这样做...但是我们必须获得一个坚实的基线才能开始,如果数据集非常大,这可能会出现问题。建立基线后,我们使用挂钩来跟踪差异
    • 您能否详细说明一下,我不确定我是否在关注?
    • 听起来您在另一组模型中保存实体的统计信息,并在发生更改时更新这些统计信息(例如:每次添加/删除文件时,您都会在某处增加/减少计数器)。这很好,除非您有 500 万个文件,并且您需要准确计算它们,以便设置统计信息。我是否正确地关注了你?
    【解决方案2】:

    如果你能满足几个条件:

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

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

    您可能需要单独处理事务更新中的添加、删除和简单更改的干扰。

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

    您甚至可以将来自事务更新的相关影响信息提供给映射器(稍微智能一点),让映射器自己评估对可能受影响的地图的影响并相应地传播信息以重新获得受影响的子作业-运行,随着更新的到来:)

    【讨论】:

      猜你喜欢
      • 2016-03-16
      • 1970-01-01
      • 2017-05-11
      • 1970-01-01
      • 2013-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多