Hive的常用優化設定

2021-10-08 21:53:09 字數 4110 閱讀 5140

-- 設定名稱

set mapred.job.name =

"test"

;-- 每個map最大輸入大小

set mapred.max.split.size =

300000000

;-- 每個map最小輸入大小

set mapred.min.split.size =

100000000

;-- 執行map前進行小檔案合併

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

--是否自動轉換為mapjoin

set hive.auto.

convert

.join

=true

;set hive.mapjoin.smalltable.filesize =

25000000

;set hive.auto.

convert

.join

.noconditionaltask =

true

;set hive.auto.

convert

.join

.noconditionaltask.size =

10000000

;-- 在map-only的任務結束時合併小檔案

set hive.

merge

.mapfiles =

true

;-- 在map-reduce的任務結束時合併小檔案

set hive.

merge

.mapredfiles =

true

;-- join 傾斜

set hive.

optimize

.skewjoin=

true

;set hive.skewjoin.

key=

100000

;-- goupby 資料傾斜

set hive.map.aggr=

true

;set hive.groupby.mapaggr.checkinterval =

100000

;set hive.groupby.skewindata=

true

;-- 合併檔案的大小

set hive.

merge

.size.per.task =

300000000

;set mapred.reduce.tasks =30;

-- 動態分割槽

set hive.

exec

.dynamic.

partition

=true

;set hive.

exec

.dynamic.

partition

.mode

=nonstrict;

-- 並行開啟

set hive.

exec

.parallel=

true

;set hive.

exec

.parallel.thread.number=

8;

hive的join方式預設common join,但是common join 在大表join小表的時候速度很慢,而且容易發生資料傾斜,而,map join 就會優化了此方面的問題,大大加快了join速度和緩解了資料傾斜!

(一). map join 到底優化在**?

因為每個mapjoin都要執行一次map,需要讀寫一次資料,所以多個mapjoin就要做多次的資料讀寫,合併mapjoin後只用讀寫一次,自然能大大加快速度。但是執行map是記憶體大小是有限制的,在一次map裡對多個小表做mapjoin就必須把多個小表都加入記憶體,為了防止記憶體溢位,所以加了hive.auto.convert.join.noconditionaltask.size引數來做限制。不過,這個值只是限制輸入的表檔案的大小,並不代表實際mapjoin時hashtable的大小。

hive的mapjoin,在join 操作在 map 階段完成,如果需要的資料在 map 的過程中可以訪問到則不再需要reduce。

小表關聯乙個超大表時,容易發生資料傾斜,可以用mapjoin把小表全部載入到內存在map端進行join,避免reducer處理。

(二).join 引數說明

如果是小表,自動選擇mapjoin:

set hive.auto.

convert

.join

=true

;# 預設為false

該引數為true時,hive自動對左邊的表統計量,如果是小表就加入記憶體,即對 小表使用map join

小表的最大檔案大小,預設為25000000,即25m

set hive.mapjoin.smalltable.filesize;
hive.mapjoin.smalltable.filesize=25000000

預設值是25mb

map join做group by 操作時,可以使用多大的記憶體來儲存資料,如果資料太大,則不會儲存在記憶體裡

set hive.mapjoin.followby.gby.localtask.max.memory.

usage

;

預設值:0.55

本地任務可以使用記憶體的百分比

set hive.mapjoin.localtask.max.memory.

usage

;

預設值: 0.90

是否將多個mapjoin合併為乙個

set hive.auto.

convert

.join

.noconditionaltask =

true

;

多個mapjoin轉換為1個時,所有小表的檔案大小總和的最大值

set hive.auto.

convert

.join

.noconditionaltask.size =

10000000

;

(三).mapjoin的注意事項

用作join的關聯欄位的字段型別最好要一致

原因:40萬行的小表處理了好幾個小時,正常情況下應該幾秒鐘就完成了。但是執行mapjoin 的local task時一直卡住,查了好久原因,結果原來是做join的關聯欄位的型別不一致,一邊是int, 一邊是string,hive解釋計畫裡顯示它們都會被轉成double再來join。我把字段型別改為一致的,瞬間就快了。照理說就算轉成double也不該這麼慢,不知道是不是hive的bug。

mapjoin 不能使用與 outer join

(四).資料傾斜

根本原因

發生資料傾斜主要是因為在資料進行shuffle的階段的時候,資料分配不均勻,導致map處理的資料量差異過大,從而在大量ruduce完成任務後,需要等待少量(1個)reduce完成才能繼續執行,任務進度卡在了99%.

導致的操作

表現任務進度長時間維持在99%(或100%),檢視任務監控頁面,發現只有少量(1個或幾個)reduce子任務未完成。因為其處理的資料量和其他reduce差異過大。單一reduce的記錄數與平均記錄數差異過大,通常可能達到3倍甚至更多。 最長時長遠大於平均時長。

典型的業務場景

(1) 空值產生的資料傾斜

場景:經常有user_id缺失的情況,如果進行join操作,會導致資料傾斜。

解決方法1: user_id為空的不參與關聯

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

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

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

hive 優化與設定

配置mapreduce.job.reduce.slowstart.completedmaps引數 該引數預設為 0.05,表示map執行 5 之後,開始reduce過程。如果集群資源不夠,有可能導致reduce把資源全搶光,可以把這個引數調整到0.8,map完成80 後才開始reduce copy ...

Hive 常用優化方法

join連線時的優化 當三個或多個以上的表進行join操作時,如果每個on使用相同的字段連線時只會產生乙個mapreduce。join連線時的優化 當多個表進行查詢時,從左到右表的大小順序應該是從小到大。原因 hive在對每行記錄操作時會把其他表先快取起來,直到掃瞄最後的表進行計算。在where字句...

Hive 筆記五 hive的優化

本地模式 嚴格模式 jvm重用 並行執行 推測還行 合併小檔案 fetch模式 1.列裁剪和分割槽裁剪 列裁剪是在查詢時只讀取需要的列 分割槽裁剪就是只讀取需要的分割槽。2.sort by代替 order by 3.group by 代替count distinct 1 common join 普通...