Hive调优
把Hive SQL当作MapReduce程序进行优化
- Hive抓取策略
- Hive允许方式
- 并行计算
- 严格模式
- Hive排序
- Hive Join
- Map-Side聚合(Combiner)
- 合并小文件
- JVM重用
Hive抓取策略
Hive中对某些情况的查询不需要MapReduce
以下SQL不会转为MapReduce来执行
- SELECT仅查询本表字段
- WHERE仅对本表字段进行条件过滤
配置方式
set hive.fetch.task.conversion=none / more;
Hive运行方式
即转化的MapReduce程序是通过本地模式执行还是集群模式执行。
- 本地模式
- 集群模式
本地模式
开启本地模式
set hive.exec.mode.local.auto=true;
注意
hive.exec.model.local.auto.inputbytes.max
默认值为128M,表示本地模式运行的情况下加载模式的最大值,若大于该配置仍会以集群方式来运行!
并行计算
开启方式
set hive.exec.parallel=true;
一次SQL计算中并行度最大值
set hive.exec.parallel.thread.number=x;
严格模式
通过禁止执行一些已知会影响Hive执行性能的操作,来达到提高Hive性能的目的。
开启方式
默认为:nostrict
set hive.mapred.mode=strict;
查询限制
- 对于分区表,必须添加where对于分区字段的条件过滤
- order by语句必须包含limit输出限制
- 限制执行笛卡尔积的查询
Hive排序
Order By
对于查询结果做全排序,只有一个reduce进行处理,当数据量较大的时候,应慎用。
严格模式下,必须结合limit来使用。
Sort By
对于单个reduce的数据进行排序。
Distribute By
分区排序,即按照指定的字段对数据进行划分到不同的Reduce中去。
经常和Sort By结合使用。
Cluster By
相当于Sort By + Distribute By,但是不能指定排序规则,可以通过Sort By 和 Distribute By自定义排序规则。
Hive Join
Map Join
在Map端完成Join操作,适用于大小表的JOIN,将小表加载至Map端的内存中,进行JOIN操作
SQL手动
在SQL语句中添加MapJoin标记(mapjoin hint)
语法
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigtable.value FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key
自动
Hive自动对左边的表进行统计量,如果是小表就加入内存,即对小表使用MapJoin.
配置
-
开启自动MapJoin
set hive.auto.convert.join = true;
-
相关配置参数:
hive.mapjoin.smalltable.filesize
大小表的判断标准,表内存大小小于该值则被认为是小表。hive.igonre.mapjoin.hint
默认值:true,是否忽略mapjoin标记
大表Join大表
避免数据倾斜
- 异常Key过滤,数据倾斜有时候是由于某个KEY对应的数据太多,而相同Key的数据会被送到相同的Reduce进行执行,从而导致内存不够,我们需要对异常的Key进行过滤,避免此类问题出现。
- 异常Key转换,有时候异常的Key锁对应的Value是有效数据,则我们应该对异常Key进行重新生成随机值,使得数据均匀被分配到不同的Reduce执行。
Map-Side聚合(Combiner)
开启方式
set hive.map.aggr=true;
相关配置参数
-
hive.gorupby.mapaggr.checkinterval
:map端group by执行聚合时处理的多少数据 -
hive.map.aggr.hash.min.reduction
:进行聚合的最小比例,对数据进行预先聚合,若聚合之后的比例小于该配置,则不会进行聚合 -
hive.map.aggr.hash.percentmemory
:map端进行聚合使用的内存的最大值 -
hive.groupby.skewindata
:是否对GroupBy产生的数据倾斜做优化,默认为false==解决数据倾斜的方法:==将一次MR分为两次MR,第一次MR负责将Key打散(使用随机分区器),优先进行一次聚合操作,再将输出的数据进行二次MR聚合。
合并小文件
文件数目小,容易在文件存储端造成压力,给HDFS造成压力,影响效率
设置合并属性
# 是否合并map输出文件
hive.merge.mapfiles=true
# 是否合并reduce输出文件
hive.merge.mapredfiles=true
# 合并文件后的大小
hive.merge.size.per.task=256 * 1000 * 1000
去重统计(COUNT DISTINCT)
当数据量大的情况,由于COUNTDISTINCT操作需要用一个Reduce Task来完成,导致一个Reduce很难完成。一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换。
控制Hive中Map与Reduce的数量
Map数量相关参数
# 一个split的最大值,即每个map处理文件的最大值
mapred.max.split.size
# 一个结点上split的最小值
mapred.min.split.size.per.node
# 一个机架上的最小值
mapred.min.split.size.per.rack
Reduce数量相关参数
# 强制指定reduce任务的数量
mapred.reduce.tasks
# 每一个reduce任务处理的数据了
hive.exec.reducers.bytes.per.reducer
# 每个任务最大的reduce数
hive.exec.reducers.max
JVM重用
适用场景
- 小文件个数过多
- TASK个数过多
开启方式
set = mapred.job.reuse.jvm.num.tasks=n; # n为插槽数
缺点
设置开启之后,Task插槽会一直站用资源,不论是否有Task在执行,直到整个Job全部完全执行完毕后,才会释放所有的Task资源。