聽說(shuō)mongodb的MapReduce是單線程的,性能很差,這是怎麼回事?差到什麼程度呢??有哪位大俠能說(shuō)說(shuō)原理。
走同樣的路,發(fā)現(xiàn)不同的人生
裡面執(zhí)行是否是單線程我不知道, 但是, 如果是生產(chǎn)環(huán)境的話, 最好還是別每次直接去訪問mapReduce 的結(jié)果,根據(jù)數(shù)據(jù)量的大小,還是會(huì)花費(fèi)一定的時(shí)間的。我們的資料是千萬(wàn)級(jí)別, 每次執(zhí)行mapReduce,大概需要5-6秒時(shí)間, 還好我們的應(yīng)用不是對(duì)即時(shí)性很高。 所以基本上就是快取2小時(shí)的數(shù)據(jù), 然後在去執(zhí)行mapReduce 取得最新的結(jié)果。
我想mongodb的效能問題,就用這篇文章來(lái)解釋吧!
http://stackoverflow.com/questions/39...
之前使用MapReduce做過類似的事情,因?yàn)楹臅r(shí),後來(lái)修改成使用聚合查詢做統(tǒng)計(jì),具體範(fàn)例如下:
> db.user.findOne()
{
"_id" : ObjectId("557a53e1e4b020633455b898"),
"accountId" : "55546fc8e4b0d8376000b858",
"tags" : [
"金牌會(huì)員",
"鉆石會(huì)員",
"鉑金會(huì)員",
"高級(jí)會(huì)員"
]
}
基本的文檔model如上,我在accountId和tags上做了索引
db.user.ensureIndex({"accountId":1, "tags":1})
現(xiàn)在要求統(tǒng)計(jì)使用者下面的tags,MapReduce設(shè)計(jì)如下:
var mapFunction = function() {
if(this.tags){
for (var idx = 0; idx < this.tags.length; idx++) {
var tag = this.tags[idx];
emit(tag, 1);
}
}
};
var reduceFunction = function(key, values) {
var cnt=0;
values.forEach(function(val){ cnt+=val;});
return cnt;
};
db.user.mapReduce(mapFunction,reduceFunction,{out:"mr1"}) //輸出到集合mr1中
結(jié)果:
> db.mr1.find().pretty()
{ "_id" : "金牌會(huì)員", "value" : 9000 }
{ "_id" : "鉆石會(huì)員", "value" : 43000 }
{ "_id" : "鉑金會(huì)員", "value" : 90000 }
{ "_id" : "銅牌會(huì)員", "value" : 3000 }
{ "_id" : "銀牌會(huì)員", "value" : 5000 }
{ "_id" : "高級(jí)會(huì)員", "value" : 50000 }
看似達(dá)到我們的效果, 我只是拿少量的數(shù)據(jù)10W做的上面的測(cè)試, 執(zhí)行的過程中,它會(huì)輸出:
> db.mapReduceTest.mapReduce(mapFunction,reduceFunction,{out:"mr1"})
{
"result" : "mr1",
"timeMillis" : 815, //耗時(shí)多久
"counts" : {
"input" : 110000, //掃描的文檔數(shù)量
"emit" : 200000, //mongo執(zhí)行計(jì)算的次數(shù)
"reduce" : 2001,
"output" : 6
},
"ok" : 1
}
因?yàn)槲襪ock的數(shù)據(jù)比較簡(jiǎn)單有規(guī)律,可以看出它的計(jì)算次數(shù)幾乎是掃描的文檔數(shù)量的二倍,後來(lái)使用隨機(jī)的數(shù)據(jù)做測(cè)試,發(fā)現(xiàn)結(jié)果更糟糕,果斷放棄MapReduce的實(shí)現(xiàn),改用其他實(shí)現(xiàn)。