備注:
Hive 版本 2.1.1
一.Hive的實(shí)現(xiàn)原理
Hive的編譯器將HQL轉(zhuǎn)換成一組操作符(Operator)
操作符是Hive的最小處理單元
每個(gè)操作符代表一道HDFS操作或者M(jìn)R Job 作業(yè)
Hive的操作符
Hive編譯器
Parser:
將SQL轉(zhuǎn)換成抽象語法樹
語法解析器:
將抽象語法樹轉(zhuǎn)換成查詢塊
邏輯計(jì)劃生成器:
將查詢塊轉(zhuǎn)換成邏輯計(jì)劃
物理計(jì)劃生成器:
將邏輯計(jì)劃轉(zhuǎn)換成物理計(jì)劃
物理計(jì)劃優(yōu)化器:
物理計(jì)劃優(yōu)化策略
編譯流程
利用Explain查看執(zhí)行計(jì)劃
語法:
:EXPLAIN [EXTENDED] query
輸出:
- 查詢語句的抽象語法樹(AST)
- 執(zhí)行計(jì)劃丌同階段間的依賴關(guān)系
- 每個(gè)階段的描述
二Hive優(yōu)化
優(yōu)化的目的:提升查詢性能,快速產(chǎn)出結(jié)果
Hive的優(yōu)化思路:
- 編譯器優(yōu)化器優(yōu)化:采用合理的優(yōu)化策略滥搭,生成高效的物理計(jì)劃
- MapReduce執(zhí)行層優(yōu)化:通過MR參數(shù)優(yōu)化色徘,提升Job運(yùn)行效率
- HDFS存儲(chǔ)層優(yōu)化:采用合理的存儲(chǔ)格式和合理的Schema設(shè)計(jì),降低IO瓶頸
2.1 選擇合理的存儲(chǔ)格式和壓縮格式
列存儲(chǔ)活逆,高壓縮比,列剪枝,過濾無用字段IO
- Orc
- Parquet
壓縮格式選擇:snappy
2.2 MR Job優(yōu)化
并行執(zhí)行
Hive產(chǎn)生的MR Job默認(rèn)是順序執(zhí)行的,如果Job之間無依賴可以并行執(zhí)行
set hive.exec.parallel=true;
本地執(zhí)行
雖然Hive能夠利用MR處理大規(guī)模數(shù)據(jù)第煮,但某些場(chǎng)景下處理的數(shù)據(jù)量非常小可以本地執(zhí)行解幼,不必提交集群
set hive.exec.mode.local.auto=true;
hive.exec.mode.local.auto.inputbytes.max(默認(rèn)128MB)
hive.exec.mode.local.auto.input.files.max(默認(rèn)4)
合并輸入小文件
如果Job輸入有很多小文件,造成Map數(shù)太多包警,影響效率
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
合并輸出小文件
set hive.merge.mapfiles=true; // map only job結(jié)束時(shí)合并小文件
set hive.merge.mapredfiles=true; // 合并reduce輸出的小文件
set hive.merge.smallfiles.avgsize=256000000; //當(dāng)輸出文件平均大小小于該值撵摆,啟動(dòng)新job合并文件
set hive.merge.size.per.task=64000000; //合并之后的每個(gè)文件大小
控制Map/Reduce數(shù)
控制Map/Reduce數(shù)來控制Job執(zhí)行的并行度
Num_Map_tasks= $inputsize/ max($mapred.min.split.size, min($dfs.block.size, $mapred.max.split.size))
Num_Reduce_tasks= min($hive.exec.reducers.max, $inputsize/$hive.exec.reducers.bytes.per.reducer)
JVM重用
JVM重利用可以使job長時(shí)間保留slot,直到作業(yè)結(jié)束
set mapred.job.reuse.jvm.num.tasks=10 //每個(gè)jvm運(yùn)行10個(gè)task
推測(cè)執(zhí)行
set hive.mapred.reduce.tasks.speculative.execution=true
set mapreduce.map.speculative=true
set mapreduce.reduce.speculative=true
一定要開啟壓縮
中間結(jié)果壓縮揽趾,減少Job跟Job之間的IO開銷
set hive.exec.compress.intermediate=true
set mapred.map.output.compression.codec=<CodecClassName>
最終結(jié)果壓縮台汇,減少存儲(chǔ)空間
set hive.exec.compress.output=true
Set mapred.output.compression.codec=<CodecClassName>
2.3 Join優(yōu)化
Hive的Join類型:
- Shuffle Join
- Broadcast Join(MapJoin)
-
Sort-Merge-Bucket Join
image.png
2.3.1 MapJoin 優(yōu)化
方式一(自動(dòng)判斷):
set.hive.auto.convert.join=true;
hive.mapjoin.smalltable.filesize // 默認(rèn)值是25mb, 小表小于25mb自動(dòng)啟動(dòng)mapjoin
方式二(手動(dòng)顯式):
select /+mapjoin(A)/ f.a,f.bfrom A t join B f on (f.a=t.a)
2.3.2 SMB Join 優(yōu)化
使用方式:
hive.optimize.bucketmapjoin= true
和mapjoin一起工作,所有要Join的表都必須對(duì)Join key做了分桶苛骨,并且大表的桶數(shù)是小表的整數(shù)倍
由于對(duì)表設(shè)計(jì)有太多的限制篱瞎,不太常用
2.4 數(shù)據(jù)傾斜
數(shù)據(jù)傾斜是指由于數(shù)據(jù)分布不均勻,個(gè)別值集中占據(jù)大部分?jǐn)?shù)據(jù)量痒芝,導(dǎo)致某一個(gè)或者幾個(gè)ReduceTask處理的數(shù)據(jù)量相對(duì)很大造成的Job運(yùn)行非常慢俐筋,甚至OOM掛掉
在SQL上,一般是由于group by 或者join shuffle key丌均勻造成的
數(shù)據(jù)傾斜是業(yè)務(wù)數(shù)據(jù)問題導(dǎo)致的严衬,如果從業(yè)務(wù)上下手避免是最好的
- 比如由于Null值引起的澄者,或者某一個(gè)特殊的key造成的數(shù)據(jù)量特別大
- 先過濾掉特殊key的數(shù)據(jù)再進(jìn)行處理
Hive自身的優(yōu)化方案:
- 由group by 引起的數(shù)據(jù)傾斜:
hive.map.aggr=true //做map端預(yù)聚合,相當(dāng)于Map端Combiner
hive.groupby.skewindata//將key的數(shù)據(jù)隨機(jī)分發(fā)到Reduce端做聚合请琳,然后再起一個(gè)Job對(duì)上一步的結(jié)果做聚合
- 由Join引起的數(shù)據(jù)傾斜(Skew Join)
set hive.optimize.skewjoin= true
set hive.skewjoin.key= 100000
// 超過閾值就判斷為skew key
2.5 Hive的優(yōu)化配置參數(shù)
hive-site.xml中更改默認(rèn)配置
在腳本中set變量
Hive的優(yōu)化配置非常多粱挡,具體情況具體分析