我們有一個看似簡單的地圖/縮小工作,每天都要通過日誌記錄數據。在開發服務器上,我們可以通過大量的文檔運行這個工作,大約1M,大概只需一分鐘,沒有任何問題。我們將作業移至生產服務器(即亞馬遜EC2服務器),作業將以非常快的速度翻閱大約50%的行,然後抓取剩餘的數據。通過數十萬個文檔可能需要幾個小時,而不是預計的一兩分鐘。所以我希望我們在地圖/縮減工作中犯了一個明顯的錯誤。蒙古地圖/減少大型收藏放緩
下面是一個簡單的輸入文檔:
{ "_id" : ObjectId("4f147a92d72b292c02000057"), "cid" : 25, "ip" : "123.45.67.89", "b" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7", "r" : "", "l" : "en-US,en;q=0.8", "ts" : ISODate("2012-01-16T19:29:22Z"), "s" : 0, "cv" : "4f143a5fd72b292d7f000007", "c" : "" }
我們查詢了一系列_id唯一的。
這裏是映射代碼:
function() { var browser = {} ,referrer = {}; browser[this.b] = { 'count': 1 }; referrer[this.r] = { 'count': 1 }; var objEmit = { 'count': 1 ,'browsers' : browser ,'referrers' : referrer }; var date = this._id.getTimestamp(); date.setHours(0); date.setMinutes(0); date.setSeconds(0); emit({'cv' : this.cv, 'date' : date, 'cid' : this.cid }, objEmit); };
這裏是降低代碼:
function (key, emits) { var total = 0 ,browsers = {} ,referrers = {}; for (var i in emits) { total += emits[i].count; for (var key in emits[i].browsers) { if (emits[i].browsers.hasOwnProperty(key)) { !(browsers[key]) && (browsers[key] = { count : 0 }); browsers[key].count += emits[i].browsers[key].count; } } for (var key in emits[i].referrers) { if (emits[i].referrers.hasOwnProperty(key)) { !(referrers[key]) && (referrers[key] = { count : 0 }); referrers[key].count += emits[i].referrers[key].count; } } } return {'count' : total, 'browsers' : browsers, 'referrers' : referrers} };
沒有敲定,我們輸出的map/reduce任務到現有的集合與 「合併」選項設置爲true。
任何幫助,非常感謝。
謝謝。 CPU的使用似乎被固定在生產上,所以這可能是在正確的軌道上。我們應該不使用微型實例,而是「超大內存」。 – Spencer
你的開發機器有什麼樣的規格?這種情況不應該有這些問題。我也會研究一下關於dev和產品的MongoDB設置。他們是相同的版本,相同的設置,相同的架構(開發和生產都是64位)? –