2010-09-28 58 views
2

我已經繼承了一個mapreduce代碼庫,它主要計算不同廣告隨時間變化的唯一用戶ID數量。對我來說,它看起來並不像是非常有效地完成,我想知道是否有人有關於如何在mapreduce中儘可能高效地進行這種計算的任何提示或建議。mapreduce中的高效設置操作

我們使用Hadoop的,但我會用僞舉一個例子,沒有所有的克魯夫特:

map(key, value): 
    ad_id = .. // extract from value 
    user_id = ... // extract from value 
    collect(ad_id, user_id) 

reduce(ad_id, user_ids): 
    uniqe_user_ids = new Set() 
    foreach (user_id in user_ids): 
    unique_user_ids.add(user_id) 
    collect(ad_id, unique_user_ids.size) 

這不是太多的代碼,它不是很難理解,但它不是很有效。我們每天都會獲得更多數據,因此我們每天都需要從一開始就查看所有廣告展示次數,以計算該廣告的唯一用戶ID數量,因此每天都需要更長時間,並使用更多內存。此外,如果沒有實際分析代碼(不確定如何在Hadoop中執行此操作),我很確定幾乎所有的工作都在創建一組唯一的ID。它也吃了大量的記憶。

我已經嘗試過使用非mapreduce解決方案,並且獲得了更好的性能(但問題在於如何按照我可以用Hadoop進行擴展的方式進行縮放),但感覺應該有一個更好的方式來做mapreduce我的代碼。對其他人來說,解決這個問題一定是一個常見的問題。

如何使用mapreduce以有效的方式實現唯一ID的計數?

回答

2

問題是,您繼承的代碼是以「我將自己確定唯一集合」而不是「讓我們利用框架爲我來做」這樣的思維方式編寫的。

我想是這樣的(僞),而不是:

map(key, value): 
    ad_id = .. // extract from value 
    user_id = ... // extract from value 
    collect(ad_id & user_id , unused dummy value) 

reduce(ad_id & user_id , unused dummy value): 
    output (ad_id , 1); // one unique userid. 

map(ad_id , 1): --> identity mapper! 
    collect(ad_id , 1) 

reduce(ad_id , set of a lot of '1's): 
    summarize ; 
    output (ad_id , unique_user_ids); 
2

尼爾斯的解決方案是好的,但因爲這是更接近原始代碼,並且只使用一個映射減少相近似替代,只需更換用布隆過濾器設置。布隆過濾器中的成員查詢具有很小的錯誤概率,但尺寸估計非常準確。