標籤:

為何Hive中的數據不均勻分布會導致數據傾斜?

如題,在下Hadoop萌新一枚,最近接觸項目的時候,執行SQL,出現了兩種現象.

(1) 數據reduce始終是停留在99%.

(2)數據reduce在某一段區間,重複擺動三次,周期相同,區間固定,然後報錯

e.g:

Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0)

Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: [Error 20001]: An error occurred while reading or writing to your custom script. It may have crashed with an error.

通過查閱資料,基本上可以確定是數據傾斜導致的.

那麼為何數據不均勻分布會導致數據傾斜?MapReduce在這個地方處理是什麼特殊之處導致的?傳統關係型資料庫的計算引擎為何沒有出現這種情況? 為何出現數據傾斜會導致這些現象?常用的解決手段是什麼(最好能附上原理依據,十分感謝)?

PS:&<&&> 那本書也看了 感覺講得很粗糙 甚至流程寫的都不是很清晰 官網資料也並不多 大神們是否能提供一些 有效的書籍 或者方法 不勝感激~


數據傾斜毒害很大,是大數應用的公敵。很可能讓你的並行作業變成串列的(超慢的task運行時間極長,以至於其他task運行時間可以忽略)

這主要是數據分布不均勻構成的,比如報表系統里,按照一級域名統計被訪問的pv數目,如果採用hive算,最終一級域名會作為key交給reduce端處理(注意相同的key需交給同一個reduce task處理,不能分給不同的),對於一些大站,比如各大門戶網站(比如新浪,搜索),他們的網頁數量極大,遠遠大於其他網站,這樣,處理大站的那些reduce task輸入數據量會大大,嚴重拖慢速度。

Hive解決方案是:

(1)建表時指定skew data,這是hive建表獨有的語法,會對這樣的數據特殊優化

(2)用戶避免在存在傾斜的欄位上進行聚集,如果很慢,沒有太好的方法。

pig里有個好方法是,先抽樣發現skew 列,之後生成兩輪mapreduce,第一輪,同一個key可能交給多個reduce task處理,第二輪,對前一輪來自多個reduce task的key進行二次聚集。


數據傾斜造成的原因,和map-reduce的原理有關係,當到達reduce端數據如果在某一個key上分布特別多的話,就會造成單個節點處理時間異常增多,從而導致整體任務耗時嚴重。

以下幾個方法可以有效避免這個問題:

1,首先分析數據,可以查看到底是什麼樣的數據分布導致某一個reduce執行那麼慢,根據分析的結果去採取第2步操作;

2,數據清洗階段,去除異常值,避免因為異常值帶來數據傾斜;

3,如果是group by 或者 count (distinct ) 語法導致數據傾斜,就用參數控制:

hive.groupby.skewindata=true

這個可以讓傳遞給reduce的數據做負載均衡處理,避免一個計算節點處理過多的數據;

4,如果是join語法造成的數據傾斜,盡量使用mapjoin將小表載入到內存中執行join,另外避免在空值異常值上做join(可以過濾掉)等;


有一種場景是特殊值的數據,例如大量null的key。處理方法是先把數據分成正常分布的數據和特殊數據,分別處理,再合併結果。


在reduce階段,數據會按照key的hash值分發到對應的上,也就是相同key一定分到一個reducer上。所以如果表中的key分布不均會導致某些reducer壓力太大,

解決辦法

一是skew table

二是對特定的值轉換為隨機值作為key


這是關於uhadoop,Hive的一些比較全的解決問題的方法和學習資料了,希望對你有所幫助吧Hadoop入門學習路線|Hadoop項目案例-檸檬學院社區Hadoop頻道


推薦閱讀:

Hive On Spark, SparkSQL On Spark, 與Spark On YARN如何定義呢?

TAG:Hadoop | Hive |