INFO-HIVE优化常用参数

适用模块

hive

具体说明

常用参数

使用示例

**yarn-site.xml 配置**
yarn.nodemanager.resource.memory-mb:配置节点最大可能物理内存
yarn.nodemanager.vmem-pmem-ratio:配置物理内存与虚拟内存比例,默认值为2.1;
yarn.scheduler.minimum-allocation-mb:配置默认 container 可申请的最小内存资源,影响单个节点 container 个数;
yarn.scheduler.maximum-allocation-mb:配置默认 container 可申请的最大内存资源,该值需大于yarn.scheduler.minimum-allocation-mb,但小于yarn.nodemanager.resource.memory-mb

**Mapreduce 相关(运行时参数):**
资源分配相关

set mapreduce.map.memory.mb=8192;
set mapreduce.reduce.memory.mb=8192;
set mapreduce.map.java.opts=-Xmx7200m;
set mapreduce.reducce.java.opts=-Xmx7200m;
set yarn.app.mapreduce.am.resource.mb=8192;

MR 任务数相关
1、减少 map 数量

set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=128000000;
set mapred.min.split.size.per.rack=256000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

2、设置 reduce 数量

<!--当HQL 存在全局计数、求和、排序及笛卡尔积时无效,默认只会生成一个 reduce-->
set mapreduce.job.reduces=200;

3、合并小文件

set hive.merge.mapfiles = true;
set hive.merge.mapredfiles= true;
set hive.merge.size.per.task = 1024000000;
set hive.merge.smallfiles.avgsize=1024000000

4、设置任务超时时间

set mapred.task.timeout=600000;

5HQL设置压缩

SET hive.exec.compress.output=true;
SET mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec;


**MR优化相关:**

设置动态分区

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions=1000;
set hive.exec.max.dynamic.partitions.pernode=1000;

mapjoin优化

set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.size=100000000;
set hive.auto.convert.join.noconditionaltask=true;
set hive.auto.convert.join.noconditionaltask.size=100000000;

分桶优化

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 端进行数据聚合>

set hive.map.aggr=true   

<!-- 生成两个 MR 任务进行处理,第一个 MR 对数据进行随机分配至 Reduce 进行部分聚合,第二个 MR 对聚合后结果再进行第二次聚合操作 --> 

<!-- groupby过程出现数据倾斜 -->

set hive.groupby.skewindata=true;
set hive.groupby.mapaggr.checkinterval=100000;

<!-- on 阶段出现数据倾斜 -->

set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;

去重复值统计——尽量不要使用count(distinct [col])

数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成(可以理解成count(distinct )会把所有数据都传输到同一台服务器然后进行去重),一般COUNT DISTINCT使用先GROUP BYCOUNT的方式替换:

SELECT datekey, COUNT(DISTINCT id) AS uv FROM a GROUP BY datekey

可以转换成:

SELECT datekey, COUNT(id) AS uv FROM (SELECT datekey,id FROM a GROUP BY datekey,id) a GROUP BY datekey;

小表关联大表

select /*+ MAPJOIN(a) */  a.c1, b.c1 ,b.c2  from a  join b  where a.c1 = b.c1    <!-- 将小表 a 加载至内存-->

键值分布集中或存在大量空值

1、将该表拆分为两部分分别关联后将结果进行 union all

2、对空值进行随机赋值后再进行关联操作

select * from (select case when a.user_id is null then concat(‘hive’,rand() ) else a.user_id end user_id_new,a.* from  log a ) a left outer join users b on  a.user_id_new = b.user_id;

**分区剪裁**

在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤。

比如:
SELECT a.id FROM a left join b ON a.id = b.url WHERE b. datekey = 2015-05-10

建议直接写成子查询:

作者:林帅