Hive優化 資料傾斜 典型案例

2021-09-10 02:54:08 字數 3111 閱讀 5998

優化

1、fetch抓取

hive.fetch.task.conversion 設定成 more 執行一些limit,select 單個字段不會跑mr程式

2、本地模式

hive.exec.mode.local.auto 的值為 true

3、表的優化

3.1、老版本hive,把資料小的表放在join的左邊,新版本已經優化了這個方法,放在join左邊跟右邊沒有區別了,

3.2、空key過濾

select n.* from (select * from nullidtable where id is not null ) n   left join ori o on n.id = o.id;

空key轉換,有時空值對應的資料不是錯誤資料,我們也需要處理,可以對這個key進行轉換,使用隨機值進行轉換,使得隨機到不同得reduce中

4、開啟 mapjoin 功能

set hive.auto.convert.join = true; 預設為 true

開啟 map 端聚合引數設定

是否在map 端進行聚合,預設為 true hive.map.aggr = true

在 map 端進行聚合操作的條目數目

hive.groupby.mapaggr.checkinterval = 100000

5、動態分割槽設定

set hive.exec.dynamici.partition=true;

set hive.exec.dynamic.partition.mode=nonstrict;

set hive.exec.mode.local.auto=true;

set hive.exec.max.dynamic.partitions=100000;

set hive.exec.max.dynamic.partitions.pernode=100000;

set hive.exec.max.created.files=100000;

6、當然了,還有我們得分區分桶概念

資料傾斜

1、合併小檔案

set hive.input.format= org.apache.hadoop.hive.ql.io.combinehiveinputformat;

2、複雜檔案增加map數量

如果map執行的非常慢的話,可以考慮增加map得數量

computeslitesize(math.max(minsize,math.min(maxsize,blocksize)))=blocksize=128m 公式,調整 maxsize 最大值。讓 maxsize 最大值低於 blocksize 就可以增加 map 的個數。

set mapreduce.input.fileinputformat.split.maxsize=100(設定最大切片值為 100m)

3、jvm重用

4、嚴格模式

5、推測執行

6、壓縮

1、空值產生的資料傾斜

場景:如日誌中,常會有資訊丟失的問題,比如日誌中的 user_id,如果取其中的 user_id 和 使用者表中的user_id 關聯,會碰到資料傾斜的問題。

解決方法1: user_id為空的不參與關聯(紅色字型為修改後)

select * from log a  join users b  on a.user_id is not null  and a.user_id = b.user_idunion allselect * from log a  where a.user_id is null;

解決方法2 :賦與空值分新的key值

select *  from log a  left outer join users b  on case when a.user_id is null then concat(『hive』,rand() ) else a.user_id end = b.user_id;

結論:方法2比方法1效率更好,不但io少了,而且作業數也少了。解決方法1中 log讀取兩次,jobs是2。解決方法2 job數是1 。這個優化適合無效 id (比如 -99 , 』』, null 等) 產生的傾斜問題。把空值的 key 變成乙個字串加上隨機數,就能把傾斜的資料分到不同的reduce上 ,解決資料傾斜問題。

2、不同資料型別關聯產生資料傾斜

場景:使用者表中user_id欄位為int,log表中user_id欄位既有string型別也有int型別。當按照user_id進行兩個表的join操作時,預設的hash操作會按int型的id來進行分配,這樣會導致所有string型別id的記錄都分配到乙個reducer中。

解決方法:把數字型別轉換成字串型別

select * from users a  left outer join logs b  on a.usr_id = cast(b.user_id as string)

3、將小表進行map的聚合,再map端放入記憶體,以供使用(reduce join轉換為map join)

使map的輸出資料更均勻的分布到reduce中去,是我們的最終目標。由於hash演算法的侷限性,按key hash會或多或少的造成資料傾斜。大量經驗表明資料傾斜的原因是人為的建表疏忽或業務邏輯可以規避的。在此給出較為通用的步驟:

1、取樣log表,哪些user_id比較傾斜,得到乙個結果表tmp1。由於對計算框架來說,所有的資料過來,他都是不知道資料分布情況的,所以取樣是並不可少的。

2、資料的分布符合社會學統計規則,貧富不均。傾斜的key不會太多,就像乙個社會的富人不多,奇特的人不多一樣。所以tmp1記錄數會很少。把tmp1和users做map join生成tmp2,把tmp2讀到distribute file cache。這是乙個map過程。

3、map讀入users和log,假如記錄來自log,則檢查user_id是否在tmp2裡,如果是,輸出到本地檔案a,否則生成的key,value對,假如記錄來自member,生成的key,value對,進入reduce階段。

4、最終把a檔案,把stage3 reduce階段輸出的檔案合併起寫到hdfs。

如果確認業務需要這樣傾斜的邏輯,考慮以下的優化方案:

1、對於join,在判斷小表不大於1g的情況下,使用map join

2、對於group by或distinct,設定 hive.groupby.skewindata=true

3、盡量使用上述的sql語句調節進行優化

hive 資料傾斜優化

hive資料傾斜 group by 中的計算均衡優化 1.map端部分聚合 先看看下面這條sql,由於使用者的性別只有男和女兩個值 未知 如果沒有map端的部分聚合優化,map直接把groupby key 當作reduce key傳送給reduce做聚合,就會導致計算不均衡的現象。雖然map有100...

Hive資料傾斜

hive資料傾斜問題 傾斜原因 map輸出資料按key hash分配到reduce中,由於key分布不均勻 或者業務資料本身的特點。等原因造成的reduce上的資料量差異過大。1.1 key分布不均勻 1.2 業務資料本身的特性 1.3 sql語句造成資料傾斜 解決方案 1 引數調節 hive.ma...

HIVE 資料傾斜

解決資料傾斜,歸根結底是使map的輸出資料更均勻的分布到reduce中去。1 join 1 其中乙個表較小,但是key集中。分發到某乙個或幾個reduce上的資料遠高於平均值 2 大表與大表,但是分桶的判斷欄位0值或空值過多。這些空值都由乙個reduce處理,非常慢 2 group by group...