1. 程式人生 > >hive sql 如何解決資料傾斜

hive sql 如何解決資料傾斜

場景:

      我有接近7億條網站訪問瀏覽資料要做一次 按 host(域名) 分割槽,訪問時間進行排序(取最先訪問) 說白了就是row_number over(partition by  host order by ftime)。 突然發現會報錯:

FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask

現象就是 reduce 99% 快一個小時,一直99%

這時候你要知道,你很可能遇到了資料傾斜的場景了。

 

方法一:

 檢視執行計劃

 explain 你的sql

例如:

 

說白了就是map 端有key ,reduce 也有key

你需要設定一些引數在map端 先聚合,這樣key到reduce 分組的時候壓力少點。

設定引數:

               set hive.groupby.skewindata=true;
                set hive.map.aggr=true;
                set hive.vectorized.execution.enabled=true;
                set hive.vectorized.execution.reduce.enabled = true;
                set hive.exec.compress.output=true;

前兩個分別是 reduce 和map 的調優,

hive.groupby.skewindata=true   有資料傾斜的時候進行負載均衡,當選項設定為 true,生成的查詢計劃會有兩個 MR Job。第一個 MR Job 中,Map 的輸出結果集合會隨機分佈到 Reduce 中,每個 Reduce 做部分聚合操作,並輸出結果,這樣處理的結果是相同的 Group By Key 有可能被分發到不同的 Reduce 中,從而達到負載均衡的目的;第二個 MR Job 再根據預處理的資料結果按照 Group By Key 分佈到 Reduce 中(這個過程可以保證相同的 Group By Key 被分佈到同一個 Reduce 中),最後完成最終的聚合操作。

set hive.map.aggr=true;

map端的提高聚合效能。

後面三個是向量計算和輸出壓縮。

 

這樣如果沒解決了的話可以嘗試對key進行隨機賦值,相當於Java自定義partition 的過程。

select case when userid is null then cast ( rand ( 47 )* 100000 as i nt )

我沒怎麼用過。

 

 

 

最後我做了host 的分組統計,觀察了資料分佈。發現前二的log數量 host 總量佔2/7,於是我放棄了Top2的計算,這樣能順利

跑出結果了。然後對top2進行統計。在union all 一下 之前的結果。特殊資料特殊對待。

 

適用場景: 資料傾斜欄位穩定,長期。

               業務上可變通。