-- 設定名稱
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 普通...