Hive SQL基本上适用大数据领域离线数据处理的大部分场景。Hive SQL的优化也是我们必须掌握的技能,而且,面试一定会问。那么,我希望面试者能答出其中的80%优化点,在这个问题上才算过关。
1. Hive优化目标
在有限的资源下,执行效率更高
常见问题
数据倾斜
map数设置
reduce数设置
其他
2. Hive执行优化
HQL --> Job --> Map/Reduce
执行计划
explain [extended] hql
样例
select col,count(1) from test2 group by col;
explain select col,count(1) from test2 group by col;
3. Hive表优化
分区
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
静态分区
动态分区
分桶
set hive.enforce.bucketing=true;
set hive.enforce.sorting=true;
数据
相同数据尽量聚集在一起
4. Hive Job优化
并行化执行
每个查询被hive转化成多个阶段,有些阶段关联性不大,则可以并行化执行,减少执行时间
set hive.exec.parallel= true;
set hive.exec.parallel.thread.numbe=8;
本地化执行
- job的输入数据大小必须小于参数:
hive.exec.mode.local.auto.inputbytes.max(默认128MB)
- job的map数必须小于参数:
hive.exec.mode.local.auto.tasks.max(默认4)
- job的reduce数必须为0或者1
-
set hive.exec.mode.local.auto=true;
当一个job满足如上条件才能真正使用本地模式:
job合并输入小文件
set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
- 合并文件数由mapred.max.split.size限制的大小决定
job合并输出小文件
set hive.merge.smallfiles.avgsize=256000000;
当输出文件平均小于该值,启动新job合并文件set hive.merge.size.per.task=64000000;
合并之后的文件大小
JVM重利用
set mapred.job.reuse.jvm.num.tasks=20;
JVM重利用可以使得JOB长时间保留slot,直到作业结束,这在对于有较多任务和较多小文件的任务是非常有意义的,减少执行时间。当然这个值不能设置过大,因为有些作业会有reduce任务,如果reduce任务没有完成,则map任务占用的slot不能释放,其他的作业可能就需要等待。
压缩数据
set hive.exec.compress.output=true;
set mapred.output.compreession.codec=org.apache.hadoop.io.compress.GzipCodec;
set mapred.output.compression.type=BLOCK;
set hive.exec.compress.intermediate=true;
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
set hive.intermediate.compression.type=BLOCK;
中间压缩就是处理hive查询的多个job之间的数据,对于中间压缩,最好选择一个节省cpu耗时的压缩方式
hive查询最终的输出也可以压缩
5. Hive Map优化
set mapred.map.tasks =10;
无效
(1) 默认map个数
default_num = total_size / block_size;
如果想增加map个数,则设置mapred.map.tasks
为一个较大的值
如果想减小map个数,则设置mapred.min.split.size
为一个较大的值
情况1:输入文件size巨大,但不是小文件
情况2:输入文件数量巨大,且都是小文件,就是单个文件的size小于blockSize
。这种情况通过增大mapred.min.split.size
不可行,需要使用combineFileInputFormat
将多个input path合并成一个InputSplit
送给mapper处理,从而减少mapper
的数量。
6. Hive Shuffle优化
- Map端
io.sort.mb
io.sort.spill.percent
min.num.spill.for.combine
io.sort.factor
io.sort.record.percent
Reduce端
mapred.reduce.parallel.copies
mapred.reduce.copy.backoff
io.sort.factor
mapred.job.shuffle.input.buffer.percent
mapred.job.shuffle.input.buffer.percent
mapred.job.shuffle.input.buffer.percent
7. Hive Reduce优化
需要reduce操作的查询
group by,
join,
distribute by,
cluster by…
order by 比较特殊,只需要一个reduce
sum,count,distinct…
聚合函数
高级查询
推测执行
mapred.reduce.tasks.speculative.execution
hive.mapred.reduce.tasks.speculative.execution
Reduce优化
numRTasks = min[maxReducers,input.size/perReducer]
maxReducers=hive.exec.reducers.max
perReducer = hive.exec.reducers.bytes.per.reducer
hive.exec.reducers.max 默认 :999
hive.exec.reducers.bytes.per.reducer 默认:1G
set mapred.reduce.tasks=10;直接设置