2012-05-23 57 views
3

我們有一個看似簡單的地圖/縮小工作,每天都要通過日誌記錄數據。在開發服務器上,我們可以通過大量的文檔運行這個工作,大約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。

任何幫助,非常感謝。

回答

0

因爲它是在開發和生產中運行的相同代碼,並且您已經在非常大的集合中運行它,並且它很快返回,所以您懷疑代碼可能有問題的任何特定原因?

您是否可能在Micro實例上運行?如果你不知道,Micro instances cap average CPU usage,這可能是通過造成龐大的數據隊列而不被允許處理它而損壞你的Map-Reduce活動(I/O沒有以相同的方式被封頂,所以不斷涌入,Linux內核然後花費大部分時間來管理它,並使事情變得更糟)。

即使CPU速度較低,從微型切換到小型也可以幫助您解決問題,因爲您可以使用恆定的CPU週期「流量」(正常機器一直都有),並且MongoDB的內部調度可能會更好地適應。

這可能之前沒有問題,因爲普通查詢「spikes」的持續時間不足以導致CPU限制打開。

+0

謝謝。 CPU的使用似乎被固定在生產上,所以這可能是在正確的軌道上。我們應該不使用微型實例,而是「超大內存」。 – Spencer

+0

你的開發機器有什麼樣的規格?這種情況不應該有這些問題。我也會研究一下關於dev和產品的MongoDB設置。他們是相同的版本,相同的設置,相同的架構(開發和生產都是64位)? –