2013-05-19 110 views
0

如何使用Map Reduce連接兩個記錄集?大多數解決方案包括在SO上發佈的解決方案都建議我發佈基於公共密鑰的記錄,並在reducer中添加它們以表示HashMap,然後採用交叉產品。 (如Join of two datasets in Mapreduce/Hadoop使用Hadoop MapReduce進行連接操作

該解決方案非常好,適用於大多數情況下,但在我的情況下,我的問題是相當不同的。我正在處理一個擁有數十億記錄的數據,並且採用兩套產品的交叉產品是不可能的,因爲在很多情況下,HashMap最終會擁有幾百萬個對象。所以我遇到了堆空間錯誤。

我需要一個更有效的解決方案。 MR的整個目標是處理我想知道的非常高的數據量,如果有任何解決方案可以幫助我避免這個問題。

+0

你做錯了什麼。這個答案實際上給你提供了唯一的方法來完成MR的連接(通過分佈式緩存和其他魔法來進行內存中連接),如果你用完堆,你顯然將太多東西放在內存中或者您的堆大小太小,請嘗試使用-XmxSIZE提高它。數據中的每個*行*是否包含數十億條記錄? – TC1

+0

如果您閱讀該答案,作者建議在內存中保留兩個列表。在我的情況下,這個列表非常大,不是因爲每個記錄的大小,而是因爲列表中的項目數量肯定超過了數百萬甚至數十億。 –

回答

0

不知道這是否對任何人都有用,但我最近面臨類似的問題。我的意圖是使用一個鍵值存儲,最可能的是Cassandra,並將其用於交叉產品。這意味着:

在A類型的行上運行時,請在Cassandra中查找密鑰。如果存在 - 將A記錄合併到現有值(B元素)中。如果沒有 - 創建一個鍵,並添加A元素作爲值。

在B類型的行上運行時,請在Cassandra中查找密鑰。如果存在 - 將B記錄合併到現有值(A元素)。如果沒有 - 創建一個鍵,並添加B元素作爲值。

這需要爲Cassandra提供額外的服務器,並且可能需要一些磁盤空間,但由於我在雲中運行(Google的bdutil Hadoop框架),因此不要認爲這應該是個問題。

0

你應該看看豬如何扭曲連接。這個想法是,如果您的數據使用相同的密鑰包含太多值(即使沒有數據歪斜),您也可以創建人造密鑰並傳播密鑰分配。這將確保每個reducer獲得的記錄數量比其他數量少。對於例如如果你將「1」加到你的關鍵字「K1」和「2」的50%之後,另外50%你將以減速器1(1K1)上的一半記錄結束,而另一半記錄到2K2。

如果之前未知鍵值的分佈,則可以使用某種採樣算法。