【问题标题】:Optimization question in MapReduce in MongoDBMongoDB中MapReduce中的优化问题
【发布时间】:2011-08-08 22:16:16
【问题描述】:

所以我和我的朋友正在尝试对一个不断添加项目的集合进行 map reduce。

基本上我们计算一些字段的平均值并将它们放入一个集合中(通过 map reduce)。

这就是问题所在,每次运行 map reduce 时,它​​都会遍历所有文档。我是 map reduce 的新手,但据我所知,如果它只在新的和/或修改的文档上运行 map reduce 并使用现有集合更新它们,似乎会非常高效。

所以我觉得没关系,我会自己做。向集合添加了“已处理:false”,当 map reduce 运行时,我传入查询过滤器“{processed:false}”,然后在 map reduce 运行后,我将“{processed:true}”设置为所有项目其中已处理 = false。

这就是问题所在。我担心边缘情况。如果在 map reduce 期间将一些项目添加到集合中会发生什么?它们从未传递到 map reduce 中,现在在 map reduce 运行后,它们的处理标志设置为 true。

如果不是将“查询过滤器”传递给 mongo,而是可以传递一个查询对象“set”,那么我可以将处理后的标志设置为 true,然后传递那些对象。

【问题讨论】:

    标签: mongodb mapreduce database nosql


    【解决方案1】:

    使它成为一个 3 步的事情。有 3 个状态,比如 UNPROCESSED、MARKEDFORPROCESSING 和 PROCESSED,然后:

    1. db.col.update({processingState:UNPROCESSED}, {$set:{processingState:MARKEDFORPROCESSING}}, false, true)
    2. 对 MARKEDFORPROCESSING 文档运行 m/r。这些保证在 m/r 开始时就已经存在。
    3. db.col.update({processingState:MARKEDFORPROCESSING }, {$set:{processingState:PROCESSED}}, false, true)
    4. 转到 1。

    这避免了您的边缘情况,并且鉴于 MongoDB 的原子更新是完全安全的。

    【讨论】:

    • 谢谢,我们也想过这个问题,但仍然存在问题……我们可能会有多个调用 mapreduce 的服务线程在运行。考虑 map reduce 是否需要 30 秒...当另一个线程进入时,第一个线程可能需要 5 秒,然后再次运行 map reduce,并将在第一个标记的相同文档上运行它...我知道这是另一个极端情况......但必须有一个优雅的解决方案?
    • 现在我想起来了,如果将markedforprocessing设置为特定的作业“id”,运行map reduce的每个线程都有一个作业id,这样其他作业就不会干扰......你觉得这样行吗?
    • 没错。将 MARKEDFORPROCESSING 替换为特定于运行它的 m/r 进程的 ID。也就是说,mongo m/r 运行单线程并且一次运行一个,因为它保留了进程的 JavaScript 上下文,因此您需要某种分片设置以使其旋转多个内核。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    相关资源
    最近更新 更多