2012-05-25 62 views
1

如何將Mapper中收集的少量元數據傳遞給Reducer?在我的具體問題中,我只想通過兩個長的值,所以我不會使用MultipleOutputFormatMultipleOutputs這些。

一些變體我曾嘗試:將少量值從Mapper傳遞到Reducer

(1)

映射

context.getCounter("Countergroup", "Counter").increment(1); 

減速

counter = context.getCounter("Countergroup", "Counter").getValue(); 

計數器不定時更新,所以Reducer中的函數調用將返回0值。



(2)

映射

context.getConfiguration().setInt("Counter", countTotal); 

減速

counter = context.getConfiguration().getInt("Counter", 0);   

當然配置不能運行作業期間改變(是值得一試)。

已經有關於這個問題的問題,但我找不到工作答案。此外,API已經改變。我正在使用Hadoop 0.20.2。



類似的問題:

Passing values from Mapper to Reducer

Accessing a mapper's counter from a reducer (這看起來很有希望,但它好像它不與0.20.2 API工作)

+0

嘗試動物園管理員。 –

+0

這裏不可能。 – DMolloy

回答

0

如果你不能找到解決方案(使用計數器將您的問題的解決方案(從映射器傳遞給Reducer中的兩個較長的值),另一種方法可以利用訂單倒置的模式。

在這種模式中,你所做的是從map中發出一個額外的鍵值對,其中鍵是東西,它成爲第一個鍵縮減器接收的事件(利用reducer以排序順序接收鍵的事實)。例如,如果您發出的鍵是從1到1000的數字值。您的虛擬鍵可以是「0」。由於Reducer以排序順序接收密鑰,所以在任何其他密鑰之前處理虛擬密鑰是有保證的。

You additionaly在新API中有SetUp()和CloseUp()方法(舊API中也有類似的方法,但我不記得名字),以利用它們只執行一次的事實在每個節點上,在該節點上的所有map/reduce任務之前/之後開始/結束。

+0

只有當你只有一個減速器時纔有效。我從OP的問題中得到的理解是,這個元數據需要被所有的縮減者使用,而不僅僅是那些碰巧運行並獲得特殊密鑰的元數據。如果您可以減少數據膨脹,則可以將元數據複用到所有密鑰,從而確保每次調用reduce()時都能看到它,並且您可以執行一些額外的輔助排序技巧來確保在迭代時首先查看元數據值羣組。 –

+0

是的,我同意它只適用於1減速器,除非數據足夠大,程序使用1減速器時速度太慢。否則,您可以發出多個鍵並寫入自定義分區器。我同意發出多個密鑰可能不是很乾淨,但是它是一種權衡,每個鍵值對都發出元數據並進行二次排序,因爲後一種方法會讓您使用大量不必要的內存。 –

+0

現在* *我喜歡(自定義分區)。通過分區器發出儘可能多的密鑰,並通過分區器確保每個reducer獲取一個副本,並通過自定義比較器確保元數據密鑰在所有真實密鑰之前出現。 –