hdoop 文本數據按列去重

問題描述:
多個數據源的文件合併,根據具體幾列(根據需求確定到底是幾列)的值確定行的唯一性,刪除掉重複的行。我們假設我們的需求是根據文本的前3列來確定行的唯一性,對於重複的行,我們隨機選取一行的數據進行保留,不需要考慮其他列的數據。


實際應用中,我們對不同的業務表合併時,可能有這方面的需求,這裏我舉的例子可能業務說明性不強,但是邏輯一樣。


是所以選擇使用mapreduce ,是因爲真實環境中我們可能需要處理的數據量特別大,使用python進行單機文本處理時,時間效率會受到限制,當文件有1T時,他是不可能一次加載,在根據你需要查找的重複行,去遍歷整個文件,這樣我們不僅效率低 還容易死機。Mapreduce正適合處理大規模數據,可以並行的執行,減少了運行時間。

   
相同顏色的表示,前三個元素是相同的,我們只需要保留相同行的其中一行就可以了,人爲數了一下最後我們需要保留32行的數據。




解決思路: 將需要的列組成key鍵

需要兩個  mapreduce 程序



第一個mapreduce
map函數{   //多個數據源數據合併,並把需要的幾列設計爲key值,


ComKey=col1+ "+" +col2+ "+" +col3; //我們必須要列之間的 “+”號,這樣可以防止元素合併時出現相同的數據
value= line    //line爲每一行的數據


context.write(key,value)


}


reduce函數{
//接收 map傳遞的key/value , 對重複的行進行疊加   
*****使用特定字符串(必須是記錄中不可能出現的)在重複行內容疊加的時候有個間隔標誌 這裏我使用 “[@123456654321@]” ,用於區別重複行的疊加。這個值可以隨便設定
 Midd= [@123456654321@]
for(Text each : value){
ComValue=ComValue+each_value+midd;
輸出 context.write(counter,"");
}




第二個mapreduce函數   //他的作用就是把剛纔的輸出文件,進行數據的裁剪


map{


int index= 每個value中 [@123456654321@] 這個字符創出現的位置


String each_value=line.substring(0, index);   //便得到了我們想要的最終結果
Context.write(Text,Text) //寫出

}


第一個mapreduce執行完後的結果 




可以看到,重複行的,每行原始數據都沒【@123456654312@】這個字符串,分割存儲到一行了。
第二個mapreduce執行完後的結果

 

我們可以看到只剩下重複的行已經去除了。


源碼:  

http://download.csdn.net/detail/tiandd12/9731296



發佈了39 篇原創文章 · 獲贊 17 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章