Mapreduce怎么處理數據傾斜


數據傾斜:

map /reduce程序執行時,reduce節點大部分執行完畢,但是有一個或者幾個reduce節點運行很慢,導致整個程序的處理時間很長,這是因為某一個key的條數比其他key多很多(有時是百倍或者千倍之多),這條key所在的reduce節點所處理的數據量比其他節點就大很多,從而導致某幾個節點遲遲運行不完。

 

用hadoop程序進行數據關聯時,常碰到數據傾斜的情況,這里提供一種解決方法。

 

(1)設置一個hash份數N,用來對條數眾多的key進行打散。

 

(2)對有多條重復key的那份數據進行處理:從1到N將數字加在key后面作為新key,如果需要和另一份數據關聯的話,則要重寫比較類和分發類(方法如上篇《hadoop job解決大數據量關聯的一種方法》)。如此實現多條key的平均分發。

 

int iNum = iNum % iHashNum;

 

String strKey = key + CTRLC + String.valueOf(iNum) + CTRLB + “B”;

 

 

(3)上一步之后,key被平均分散到很多不同的reduce節點。如果需要和其他數據關聯,為了保證每個reduce節點上都有關聯的key,對另一份單一key的數據進行處理:循環的從1到N將數字加在key后面作為新key

 

for(int i = 0; i < iHashNum; ++i){

 

String strKey =key + CTRLC + String.valueOf(i) ;

 

output.collect(new Text(strKey), new Text(strValues));}

 

以此解決數據傾斜的問題,經試驗大大減少了程序的運行時間。但此方法會成倍的增加其中一份數據的數據量,以增加shuffle數據量為代價,所以使用此方法時,要多次試驗,取一個最佳的hash份數值。

 

======================================

 

注:用上述的方法雖然可以解決數據傾斜,但是當關聯的數據量巨大時,如果成倍的增長某份數據,會導致reduce shuffle的數據量變的巨大,得不償失,從而無法解決運行時間慢的問題。

 

有一個新的辦法可以解決 成倍增長數據 的缺陷:

 

在兩份數據中找共同點,比如兩份數據里除了關聯的字段以外,還有另外相同含義的字段,如果這個字段在所有log中的重復率比較小,則可以用這個字段作為計算hash的值,如果是數字,可以用來模hash的份數,如果是字符可以用hashcode來模hash的份數(當然數字為了避免落到同一個reduce上的數據過多,也可以用hashcode),這樣如果這個字段的值分布足夠平均的話,就可以解決上述的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM