2014-08-31 83 views
0

我有兩個非常大的數據集(表)在HDFS上。我想在某些列上加入,然後在某些列上將它們分組爲,然後在某些列上執行某些組功能在MapReduce作業中通過Reducer中的文本輸入值迭代多次

我的步驟是:

1-創建兩個職位。

2-在第一作業,在映射器讀取每個數據集作爲地圖 輸入值的行和發射連接列值作爲地圖輸出密鑰和 其餘列值作爲地圖輸出值。

映射完成後,MapReduce框架根據映射輸出鍵執行混洗並將所有映射輸出值組合成 。

然後,在縮減器中它讀取每個映射輸出鍵及其值,其中包括來自兩個數據集的多行 。

我想要的是迭代減少輸入值多次,以便我可以執行笛卡爾乘積。

舉例說明:

比方說,連接鍵X,我有一個數據集100場比賽,並 200從其他比賽。這意味着加入他們加入密鑰x 產生100 * 200 = 20000組合。我想發出NullWritable爲 減少輸出鍵和每個笛卡爾 產品減少輸出值。

一個例子輸出可能是:

用於連接密鑰x:

從(nullWritable),(第一(1),第二(1))

超過(nullWritable),(第一(1),第二(200))

要(nullWritable),(1(100),第二(200))

我怎麼能這樣做?

我只能迭代一次。而且我無法兌現價值,因爲它們不適合記憶。

3-如果我這樣做,我將開始第二項工作,它將第一個 作業的結果文件作爲輸入文件。在映射器中,我發出組列' 值作爲映射輸出鍵,其餘列的值作爲映射 輸出值。然後在reducer中迭代每個鍵的值,I 在sum,avg,max,min等某些列上執行一些函數。

非常感謝。

回答

0

由於您的第一個MR作業使用連接鍵作爲映射輸出鍵,因此您的第1個reducer將爲每個reduce調用獲取(K join_key,列表< V>值)。你可以做的只是將兩個單獨的值分開,分別用於數據源,並使用嵌套for循環做笛卡爾積。

+0

亨利,謝謝你的回覆。但是我怎麼能把它們分開而不把它們存入內存? – digitalmert 2014-08-31 07:33:51

+0

@digitalmert,我認爲這些值已經被提取到內存中,因爲它們都存在於列表中。你的意思是你的兩個文件都很大,加入密鑰的基數非常小,即使是虛擬減速器也會導致OOM錯誤? – 2014-09-01 01:51:59

+0

是的。由於連接鍵的值可能包含來自兩個文件的許多行,因此該值可能不適合內存。對於鍵x,該值可能包含來自其他表的數百萬行。如果我嘗試將一個表的行讀入內存,那麼請跨越生產,這可能會導致內存不足錯誤。出於可擴展性的原因,我不想這樣做。有沒有一種方法可以爲這種情況提出建議? – digitalmert 2014-09-01 05:52:09