【问题标题】:Is Mongodb Aggregation framework faster than map/reduce?Mongodb聚合框架比map/reduce更快吗?
【发布时间】:2012-12-04 05:04:02
【问题描述】:

mongodb 2.2引入的聚合框架,相比map/reduce有什么特别的性能提升吗?

如果是,为什么以及如何以及多少钱?

(我自己已经做过测试,性能差不多)

【问题讨论】:

  • “几乎”一样吗?有哪些基准?你的言论基本没有意义。你在比较猫和牛。此外,您自己也知道 MR 仍然仅限于单线程......所以:毫无意义的问题,因此 -1
  • @user1833746 这是一个问题,我不想解释我的基准。我要求知道这个问题的新答案。请投票让其他人回答。
  • 你看过这个问题(和答案)吗? stackoverflow.com/questions/12139149/…
  • @Asya 是的,请参阅下面的基准测试
  • 请参考此链接了解更多。 runnable.com/blog/…

标签: performance mongodb mapreduce aggregation-framework


【解决方案1】:

我亲自运行的每个测试(包括使用您自己的数据)都表明聚合框架比 map reduce 快几倍,并且通常快一个数量级。

只取您发布的数据的 1/10(但不是清除操作系统缓存,而是先预热缓存 - 因为我想测量聚合的性能,而不是需要多长时间来分页数据)我得到了这个:

MapReduce:1,058 毫秒
聚合框架:133ms

从聚合框架中删除 $match 并从 mapReduce 中删除 {query:}(因为两者都只使用索引,这不是我们想要测量的)并通过 key2 对整个数据集进行分组,我得到了:

MapReduce:18,803 毫秒
聚合框架:1,535 毫秒

这些和我之前的实验非常吻合。

【讨论】:

  • 有关此问题的其他 cmets,请参阅stackoverflow.com/questions/12139149/…的答案
  • 感谢您回答问题的第一部分!第二部分呢?为什么以及如何?你有什么要补充的吗?感谢您的任何意见。
  • 这在文档中有介绍 - 但简而言之,聚合在服务器 (C++) 中本地运行,MapReduce 生成单独的 javascript 线程来运行 JS 代码。
【解决方案2】:

我的基准:

== 数据生成 ==

用大约 350 个字节轻松生成 400 万行(使用 python)。 每个文档都有这些键:

  • key1、key2(两个随机列用于测试索引,一个基数为 2000,一个基数为 20)
  • longdata:增加每个文档大小的长字符串
  • 值:一个简单的数字 (const 10) 来测试聚合

db = Connection('127.0.0.1').test # mongo connection
random.seed(1)
for _ in range(2):
    key1s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(10)]
    key2s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(1000)]
    baddata = 'some long date ' + '*' * 300
    for i in range(2000):
        data_list = [{
                'key1': random.choice(key1s),
                'key2': random.choice(key2s),
                'baddata': baddata,
                'value': 10,
                } for _ in range(1000)]
        for data in data_list:
            db.testtable.save(data)
mongo 中的总数据大小约为 6GB。 (在 postgres 中为 2GB)

== 测试 ==

我做了一些测试,但一个足以比较结果:

注意:每次查询后都会重新启动服务器,并清理操作系统缓存,以忽略缓存的影响。

QUERY:用key1=somevalue 聚合所有行(大约200K 行)并为每个key2 求和value

  • 映射/减少 10.6 秒
  • 聚合 9.7 秒
  • 10.3 秒组

查询:

映射/减少:

db.testtable.mapReduce(function(){emit(this.key2, this.value);}, function(key, values){var i =0; values.forEach(function(v){i+=v;}); return i; } , {out:{inline: 1}, query: {key1: '663969462d2ec0a5fc34'} })

聚合:

db.testtable.aggregate({ $match: {key1: '663969462d2ec0a5fc34'}}, {$group: {_id: '$key2', pop: {$sum: '$value'}} })

组:

db.testtable.group({key: {key2:1}, cond: {key1: '663969462d2ec0a5fc34'}, reduce: function(obj,prev) { prev.csum += obj.value; }, initial: { csum: 0 } })

【讨论】:

  • group 不是聚合框架,它是 map/reduce 的一部分。这就是它具有reduce功能的原因。在这里查看区别:docs.mongodb.org/manual/reference/command/groupdocs.mongodb.org/manual/reference/aggregation/#_S_group 如果您使用聚合框架,您将调用 db.collection.aggregate( [ pipeline ] )
  • 我有一个建议:为什么不取出查询并在整个集合上运行相同的东西,看看性能是否有差异。
  • 您的基准测试的另一个问题是您清除了操作系统缓存吗?因此,您主要测量将数据分页到 RAM 所需的时间。它使实际性能数字相形见绌,而且这不是一个现实的场景。
猜你喜欢
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多