Blog
hive-10 企业级调优
执行计划
基本语法:
EXPLAIN [EXTENED | DEPENDENCY | AUTHORIZATION] query
查看sql生成的MR执行计划
Fetch抓取
fetch抓取是指Hive中对某些情况的查询可以不必使用MapReduce计算
set hive.fetch.task.conversion;
- none 全部都走mr
- 默认more
本地模式
Hive可以通过本地模式在单台机器上处理所有的任务,对于小数据集,执行时间可以明显缩短
可以设置hive.exec.mode.local.auto为true来让hive在适当的时候自动启动这个优化
set hive.exec.mode.local.auto=true; // 开启本地mr
// 设置local mr的最大输入数据量,当输入数据量小于这个值时采用local mr的方式,默认为134217728即128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
// 设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max=10
表的优化
小表大表join(MapJoin)
小表放在join的左边,可以使用mapjoin让小表的维度表先进内存,在map端完成join
新版的hive已经对小表join大表和大表join小表进行了优化
- 设置自动选择MapJoin
- set hive,auto,convert.join=true (默认为true)
- 大表和小表的阈值设置(默认25M以下是小表)
- set hive,mapjoin.smalltable.filesize=25000000;
大表join大表
- 空key过滤
- 非inner join时使用
- 不需要字段为NULL的
- 设置reduce个数
set mapreduce.job.reduces=5;
- 使用分桶表
- 将大表拆成小表逐个小表join大表
- a.id=b.id 根据id哈希分桶 相同id放到一样的桶里
- set hive.optimize.bucketmapjoin=true
- set hive.optimize.bucketmapjoin.sortedmerge=true
- set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat
Group By
默认情况下Map阶段同一key数据分发给一个reduce,当一个key数据过大时就会数据倾斜
并不是所有的聚合操作都需要在reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果
- 是否在map端进行聚合,默认为true
- set hive.map.aggr=true
- 在map端进行聚合操作的条目数目
- set hive.groupby.mapaggr.checkinterval=100000
- 有数据倾斜的时候进行负载均衡 默认是false
- set hive.groupby.skwindata=true
Count(Distinct)去重统计
数据量小的时候无所谓,数据量大的时候由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY 再COUNT的方式来替换,但是需要注意group by造成的数据倾斜问题
行列过滤
少用 * 尽可能指定列名
小文件进行合并
- 在map执行前合并小文件,减少map数
- set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
在Map-Reduce的任务结束时合并小文件的设置:
- 在map-only任务结束时合并小文件,默认true
- set hive.merge.mapfiles=true
- 在map-reduce任务结束时合并小文件,默认false
- set hive.merge.mapredfiles=true
- 合并文件的大小,默认256M
- set hive.merge.size.per.task=268435456
- 当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
- set hive.merge.smallfiles.avgsize=16777216
合理设置reduce数
调整reduce个数方法一
- 每个reduce处理的数据量默认是256M
- hive.exec.reducers.bytes.per.reducer=256000000
- 每个任务最大的reduce数,默认为1009
- hive.exec.reducers.max=1009
- 计算reducer数的公式
- N=min(参数2, 总输入数据量 / 参数1)
- 参数2 = 1009
调整reduce个数方法二
- 在hadoop的mapred-default.xml文件中修改
- 设置每个job的reduce个数
- set mapreduce.job.reducers=15
reduce个数并不是越多越好
- 启动资源和时间消耗
- 有多少个reduce就会产生多少个文件
并行执行
- 打开任务并行执行
- set hive.exec.parallel=true
- 同一个sql允许最大并行度,默认为8
- set hive.exec.parallel.thread.number=8
严格模式
- 对于分区表必须填写分区
- set hive.strict.checks.no.partition.filter=true
- 使用order by 必须使用limit
- set hive.strict.checks.orderby.no.limit=true
- 临时启用笛卡尔积
- set hive.strict.checks.cartesian.product=true