MapReduce初級案例——單表關聯(lián)
“ 單表關聯(lián)”這個實例要求從給出的數(shù)據(jù)中尋找所關心的數(shù)據(jù),它是對原始數(shù)據(jù)所包含信息的挖掘。下面進入這個實例。
1 .實例描述
實例中給出 child-parent(孩子——父母)表,要求輸出 grandchild-grandparent(孫子——爺奶)表。
樣例輸入如下所示。
file:
家族樹狀關系譜:
樣例輸出如下所示。
file:
2 .設計思路
分析這個實例,顯然需要進行單表連接,連接的是左表的 parent 列和右表的 child 列,且左表和右表是同一個表。
連接結果中除去連接的兩列就是所需要的結果——“ grandchild–grandparent”表。要用MapReduce 解決這個實例, 首先應該考慮如何實現(xiàn)表的自連接; 其次就是連接列的設置;最后是結果的整理。
考慮到 MapReduce 的 shuffle 過程會將相同的 key 會連接在一起,所以可以將 map 結果的 key 設置成待連接的列,然后列中相同的值就自然會連接在一起了。再與最開始的分析聯(lián)系起來:
要連接的是左表的 parent 列和右表的 child 列,且左表和右表是同一個表,所以在 map階段將讀入數(shù)據(jù)分割成 child 和 parent 之后,會將 parent 設置成 key, child 設置成 value進行輸出,并作為左表;再將同一對 child 和 parent 中的 child 設置成 key, parent 設置成value 進行輸出,作為右表。
為了區(qū)分輸出中的左右表,需要在輸出的 value 中再加上左右表的信息,比如在 value 的 String 最開始處加上字符 1 表示左表,加上字符 2 表示右表。
這樣在 map 的結果中就形成了左表和右表,然后在 shuffle 過程中完成連接。 reduce 接收到連接的結果,其中每個 key 的 value-list 就包含了“ grandchild–grandparent”關系。
取出每個key 的 value-list 進行解析,將左表中的 child 放入一個數(shù)組, 右表中的 parent 放入一個數(shù)組,然后對兩個數(shù)組求笛卡爾積就是最后的結果了。
3 .程序代碼
程序代碼如下所示。

4 .代碼結果
準備測試數(shù)據(jù)
通過 Eclipse 下面的“ DFS Locations”在“ /user/hadoop”目錄下創(chuàng)建輸入文件“ STjoin_in”文件夾( 備注:“ STjoin_out”不需要創(chuàng)建。)如圖 4.4-1 所示,已經(jīng)成功創(chuàng)建。
然后在本地建立一個 txt 文件,通過 Eclipse 上傳到“ /user/hadoop/STjoin_in”文件夾中,一個 txt 文件的內(nèi)容如“實例描述”那個文件一樣。如圖 4.4-2 所示,成功上傳之后。
從 SecureCRT 遠處查看“ Master.Hadoop”的也能證實我們上傳的文件,顯示其內(nèi)容如圖 4.4-3 所示:
運行詳解
( 1) Map 處理:
map 函數(shù)輸出結果如下所示。
( 2) Shuffle 處理
在 shuffle 過程中完成連接。
首先由語句“ 0 != grandchildnum && 0 != grandparentnum”得知,只要在“ value-list”中沒有左表或者右表,則不會做處理,可以根據(jù)這條規(guī)則去除無效的 shuffle 連接。
然后根據(jù)下面語句進一步對有效的 shuffle 連接做處理。
針對一條數(shù)據(jù)進行分析:
分析結果: 左表用“ 字符 1”表示, 右表用“ 字符 2”表示,上面的
中的“ key”表示左表與右表的連接鍵。而“ value-list”表示以“ key”連接的左表與右表的
相關數(shù)據(jù)。
根據(jù)上面針對左表與右表不同的處理規(guī)則,取得兩個數(shù)組的數(shù)據(jù)如下所示:
然后根據(jù)下面語句進行處理。
處理結果如下面所示:
其他的有效 shuffle 連接處理都是如此。
(3)查看運行結果
這時我們右擊 Eclipse 的“ DFS Locations”中“ /user/hadoop”文件夾進行刷新,這時會發(fā)現(xiàn)多出一個“ STjoin_out”文件夾,且里面有 3 個文件,然后打開雙其“ part-r-00000”文件,會在 Eclipse 中間把內(nèi)容顯示出來。如圖 4.4-4 所示。