Mongodb聚合框架比map/reduce更快吗?
Posted
技术标签:
【中文标题】Mongodb聚合框架比map/reduce更快吗?【英文标题】:Is Mongodb Aggregation framework faster than map/reduce? 【发布时间】:2012-12-04 05:04:02 【问题描述】:mongodb 2.2引入的聚合框架,相比map/reduce有什么特别的性能提升吗?
如果是,为什么以及如何以及多少钱?
(我自己已经做过测试,性能差不多)
【问题讨论】:
“几乎”一样吗?有哪些基准?你的言论基本没有意义。你在比较猫和牛。此外,您自己也知道 MR 仍然仅限于单线程......所以:毫无意义的问题,因此 -1 @user1833746 这是一个问题,我不想解释我的基准。我要求知道这个问题的新答案。请投票让其他人回答。 你看过这个问题(和答案)吗? ***.com/questions/12139149/… @Asya 是的,请参阅下面的基准测试 请参考此链接了解更多。 runnable.com/blog/… 【参考方案1】:我亲自运行的每个测试(包括使用您自己的数据)都表明聚合框架比 map reduce 快几倍,并且通常快一个数量级。
只取您发布的数据的 1/10(但不是清除操作系统缓存,而是先预热缓存 - 因为我想测量聚合的性能,而不是需要多长时间来分页数据)我得到了这个:
MapReduce:1,058 毫秒 聚合框架:133ms
从聚合框架中删除 $match 并从 mapReduce 中删除 query:(因为两者都只使用索引,这不是我们想要测量的)并通过 key2 对整个数据集进行分组,我得到了:
MapReduce:18,803 毫秒 聚合框架:1,535 毫秒
这些和我之前的实验非常吻合。
【讨论】:
有关此问题的其他 cmets,请参阅***.com/questions/12139149/…的答案 感谢您回答问题的第一部分!第二部分呢?为什么以及如何?你有什么要补充的吗?感谢您的任何意见。 这在文档中有介绍 - 但简而言之,聚合在服务器 (C++) 中本地运行,MapReduce 生成单独的 javascript 线程来运行 JS 代码。【参考方案2】:我的基准:
== 数据生成 ==
用大约 350 个字节轻松生成 400 万行(使用 python)。 每个文档都有这些键:
key1、key2(两个随机列用于测试索引,一个基数为 2000,一个基数为 20) longdata:增加每个文档大小的长字符串 值:一个简单的数字 (const 10) 来测试聚合
mongo 中的总数据大小约为 6GB。 (在 postgres 中为 2GB)
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)
== 测试 ==
我做了一些测试,但一个足以比较结果:
注意:每次查询后都会重新启动服务器,并清理操作系统缓存,以忽略缓存的影响。
QUERY:用key1=somevalue
聚合所有行(大约200K 行)并为每个key2
求和value
查询:
映射/减少:
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/group 和 docs.mongodb.org/manual/reference/aggregation/#_S_group 如果您使用聚合框架,您将调用 db.collection.aggregate( [ pipeline ] ) 我有一个建议:为什么不取出查询并在整个集合上运行相同的东西,看看性能是否有差异。 您的基准测试的另一个问题是您清除了操作系统缓存吗?因此,您主要测量将数据分页到 RAM 所需的时间。它使实际性能数字相形见绌,而且这不是一个现实的场景。以上是关于Mongodb聚合框架比map/reduce更快吗?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Spark 比 Hadoop Map Reduce 快
MongoDB Map Reduce:自动创建的索引名称太长,可以自定义吗?