Mongodb高級(jí)篇-MapReduce

Mongodb支持使用javascript編寫mapreduce函數(shù)來做分布式數(shù)據(jù)處理胎署。然而,這種強(qiáng)大是有代價(jià)的:MapReduce非常慢,不應(yīng)該用在實(shí)時(shí)的數(shù)據(jù)分析中。

舉個(gè)MapReduce使用的例子拍屑,我們有一個(gè)orders表,包含cust_id,amount,status三個(gè)字段坑傅,現(xiàn)在我們有統(tǒng)計(jì)同一個(gè)cust_id的訂單的總額僵驰。

可以像下面這樣寫:

map-reduce

執(zhí)行順序顯而易見:

1、執(zhí)行query篩選出特定數(shù)據(jù)

2唁毒、執(zhí)行map返回鍵值對(duì)蒜茴,這里的值可以是一個(gè)list

3、執(zhí)行reduce對(duì)value求sum

4浆西、得到名為order_totals的結(jié)果

上面這個(gè)例子是掛在官網(wǎng)上的粉私。但是實(shí)際使用時(shí)按照這個(gè)寫就是無(wú)法通過....

詳細(xì)命令:

db.runCommand(
{
mapreduce : 字符串,集合名,
map : 函數(shù),見下文
reduce : 函數(shù)室谚,見下文
[, query : 文檔毡鉴,發(fā)往map函數(shù)前先給過渡文檔]
[, sort : 文檔崔泵,發(fā)往map函數(shù)前先給文檔排序]
[, limit : 整數(shù)秒赤,發(fā)往map函數(shù)的文檔數(shù)量上限]
[, out : 字符串猪瞬,統(tǒng)計(jì)結(jié)果保存的集合]
[, keeptemp: 布爾值,鏈接關(guān)閉時(shí)臨時(shí)結(jié)果集合是否保存]
[, finalize : 函數(shù)入篮,將reduce的結(jié)果送給這個(gè)函數(shù)陈瘦,做最后的處理]
[, scope : 文檔,js代碼中要用到的變量]
[, jsMode : 布爾值,是否減少執(zhí)行過程中BSON和JS的轉(zhuǎn)換潮售,默認(rèn)true] //注:false時(shí) BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可處理非常大的mapreduce,//true時(shí)BSON-->js-->map-->reduce-->BSON
[, verbose : 布爾值痊项,是否產(chǎn)生更加詳細(xì)的服務(wù)器日志,默認(rèn)true]
}
);

找了一個(gè)簡(jiǎn)單一點(diǎn)的例子酥诽,可以嘗試做一下鞍泉。

首先生成1000條測(cè)試數(shù)據(jù)。

for (var i=0; i<1000; i++) { 
db.t.insert({
"name" : "user"+i,
"age":i ,
"created_at" : new Date()
});
 }

創(chuàng)建map函數(shù):

var m=function(){
emit(this.age,this.name);
}

emit:返回一個(gè)鍵值對(duì)肮帐。emit的第一個(gè)參數(shù)是key咖驮,就是分組的依據(jù),這是自然是age了训枢,后一個(gè)是value托修,可以是要統(tǒng)計(jì)的數(shù)據(jù),下面會(huì)說明恒界,value可以是JSON對(duì)象睦刃。

這樣m就會(huì)把送過來的數(shù)據(jù)根據(jù)key分組了,可以想象成如下結(jié)構(gòu):

第一組
{key:0,values: ["name_6","name_12","name_18"]
第二組
{key:1,values: ["name_1","name_7","name_13","name_19"]
......

第二步就是簡(jiǎn)化了十酣,編寫reduce函數(shù):

var r=function(key,values){
var ret={age:key,names:values};
return ret;
}

reduce函數(shù)會(huì)處理每一個(gè)分組涩拙,參數(shù)也正好是我們想像分組里的key和values。

這里reduce函數(shù)只是簡(jiǎn)單的把key和values包裝了一下耸采,因?yàn)椴挥迷趺刺幚砭褪俏覀兿胍慕Y(jié)果了兴泥,然后返回一個(gè)對(duì)象。對(duì)象結(jié)構(gòu)正好和我們想象的相符洋幻!

最后郁轻,還可以編寫finalize函數(shù)對(duì)reduce的返回值做最后處理:

var f=function(key,rval){
if(key==0){
rval.msg="a new life,baby!";
}
return rval
}

這里的key還是上面的key,也就是還是age,rval是reduce的返回值文留,所以rval的一個(gè)實(shí)例如:{age:0,names:["name_6","name_12","name_18"]},

這里判斷 key 是不是 0 ,如果是而在 rval 對(duì)象上加 msg 屬性好唯,顯然也可以判斷 rval.age==0,因?yàn)?key 和 rval.age 是相等的嘛!燥翅!

db.runCommand({
    mapreduce:"t",
    map:m,
    reduce:r,
    finalize:f,
    out:"t_age_names"
    }
)

db.t_age_names.find()

結(jié)果導(dǎo)入到 t_age_names 集合中骑篙,查詢出來正是想要的結(jié)果,看一下文檔的結(jié)構(gòu)森书,不難發(fā)現(xiàn)靶端,_id 就是 key谎势,value 就是處理后的返回值。

map-reduce的性能優(yōu)化

這篇文章總結(jié)的很好了杨名,不再贅述:MongoDB MapReduce 性能提升20倍的優(yōu)化寶典

map-reduce運(yùn)行于sharding

比較一下map-reduce運(yùn)行于sharding和單個(gè)實(shí)例下的性能脏榆。

插入10萬(wàn)條數(shù)據(jù):

for (var i=0; i<100000; i++) {
 db.t.insert({"name" : "user"+i,"age":i ,"created_at" : new Date()}); 
}

用map-reduce來查詢sharding下實(shí)例:

db.runCommand({ mapreduce:"t",    map:m,    reduce:r,    finalize:f,  sort:{"age":-1},   out:"t_age_names"    })

{
    "result" : "t_age_names",
    "timeMillis" : 5082,
    "counts" : {
        "input" : 101000,
        "emit" : 101000,
        "reduce" : 1000,
        "output" : 100000
    },
    "ok" : 1
}

運(yùn)行時(shí)間是5秒左右。

在單機(jī)單實(shí)例下運(yùn)行:

{
    "result" : "t_age_names",
    "timeMillis" : 4820,
    "counts" : {
        "input" : 101000,
        "emit" : 101000,
        "reduce" : 1000,
        "output" : 100000
    },
    "ok" : 1
}

單機(jī)單實(shí)例下只需要4.8秒台谍。比單機(jī)sharding要快须喂。(因?yàn)閟harding是有開銷的)。

參考資料:

http://docs.mongodb.org/v2.6/core/map-reduce/

http://www.cnblogs.com/loogn/archive/2012/02/09/2344054.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趁蕊,一起剝皮案震驚了整個(gè)濱河市坞生,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌掷伙,老刑警劉巖是己,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異任柜,居然都是意外死亡卒废,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門乘盼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來升熊,“玉大人,你說我怎么就攤上這事绸栅〖兑埃” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵粹胯,是天一觀的道長(zhǎng)蓖柔。 經(jīng)常有香客問我,道長(zhǎng)风纠,這世上最難降的妖魔是什么况鸣? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮竹观,結(jié)果婚禮上镐捧,老公的妹妹穿的比我還像新娘。我一直安慰自己臭增,他們只是感情好懂酱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著誊抛,像睡著了一般列牺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拗窃,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天瞎领,我揣著相機(jī)與錄音泌辫,去河邊找鬼。 笑死九默,一個(gè)胖子當(dāng)著我的面吹牛震放,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荤西,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼澜搅,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼伍俘!你這毒婦竟也來了邪锌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤癌瘾,失蹤者是張志新(化名)和其女友劉穎觅丰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妨退,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妇萄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咬荷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冠句。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幸乒,靈堂內(nèi)的尸體忽然破棺而出懦底,到底是詐尸還是另有隱情,我是刑警寧澤罕扎,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布聚唐,位于F島的核電站,受9級(jí)特大地震影響腔召,放射性物質(zhì)發(fā)生泄漏杆查。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一臀蛛、第九天 我趴在偏房一處隱蔽的房頂上張望亲桦。 院中可真熱鬧,春花似錦浊仆、人聲如沸客峭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)桃笙。三九已至,卻和暖如春沙绝,著一層夾襖步出監(jiān)牢的瞬間搏明,已是汗流浹背鼠锈。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留星著,地道東北人购笆。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像虚循,于是被迫代替她去往敵國(guó)和親同欠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容