Hive优化

1. 分区

通过限定分区来限定扫描的范围, 查询一定要指定分区, 否则会全表扫描的

2. 优先级问题

() > not > and > or

3. 连接问题

  1. 只支持等值连接,不支持非等值连接
  2. 内连接小表放前面,大表放后面
  3. 连接小表可以使用mapjoin
    小表可以放进内存当中【维度表、或者行数<2w】
    小表是不能作为驱动表的【比如left join的左表】
    select /*+MAPJOIN(b)*/ a.k, a.v from a join b on a.k = b.k
    

4. SQL的执行顺序的问题

  1. from -> join -> where -> group -> 聚合函数 -> having -> 算数函数 -> select -> distinct -> order
  2. 既然是这样子的话,那么我们的sql在书写的时候就要注意在join之前过滤下数据
select a.x,b.x from a full|left|right outer join b on (a.key=b.key and a.ds=d1 and b.ds=d1) 

改写成 

Select t1.x ,t2.x from (select * from a where ds=d1) t1
full outer join (select * from  b where ds=d1) t2 on t1.key=t2.key

5. 左右连接驱动表的问题

  1. 驱动表的过滤条件放在on中会存在问题,应该在left join之前或者之后进行过滤
select a.x,b.x from a left outer join b on (a.key=b.key and a.ds=d1 and b.ds=d1)

应该写成

select a.x ,b.x  from a
left outer join b on a.key=b.key and b.ds=d1 
where a.ds=d1

或者

select t1.x ,t2.x from (select * from a where ds=d1) t1
Left outer join b t2 on t1.key=t2.key and t2.ds=d1

6. 多表连接

select 
* 
from a 
join b 
on a.k = b.k 

join c 
on c.k = b.k

7. 内连接和笛卡尔积 【笛卡尔积只有一个reduce很慢】

--这是内连接
select
*
from
a join b 
on a.k = b.k 

-- 这句话在MySQL或者oracle等价内连接,但是在hive就是笛卡尔积
-- 只有连接条件时不等式是才可使用笛卡尔积!
select * from a, b where a.k = b.k 

8. distinct+join问题

如果一张表应该是distinct的,但是实际上却不是这样。那么我们要先distinct放到子查询中然后在进行join!

9. in/exists子查询问题

  1. 不支持in后面的子查询,但是可以是列表。如province in (‘gd’,’gx’)
  2. 通过 semi join实现 【半连接-就是说join到之后返回a表记录,且只返回一次】
SELECT a.key, a.value FROM a WHERE a.key in (SELECT b.key FROM B)

可以写成:

SELECT a.key, a.val FROM a LEFT SEMI JOIN b on (a.key = b.key)

10. 子查询问题

  1. from后面支持子查询,where后面不支持子查询

11. 查询字段加快速度的方法

  1. 如果where 里面没有除了分区外的过滤条件,使用 * 不用生成map/reduce可以加快速度。

12. 慎用order by

  1. 全局排序,只有一个reduce

13. 压缩+设置reduce+设置group

  1. 结果压缩:(默认不压缩)
set hive.exec.compress.output=true;
  1. 压缩算法:(这个一般不用设,默认是gzip)
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
  1. 特殊情况下设置reduce的个数
set mapred.reduce.tasks=n
  1. 数据严重倾斜时在sql前面加上
set hive.groupby.skewindata = true
-- 数据严重倾斜通常发生在 group by,其中维度值少,维度对应的记录数特别大的时候。

14. group和union的问题

先group然后进行union的话,会每一个group启动一个MR任务,然后在进行汇总。性能非常低下!
如果先union然后进行group的话,性能就会提升很多!

15. case when then 和子查询

使用case when then来代替子查询可以减少job数量,优化效率很高!

16. count+distinct问题

例句1SELECT
        COUNT(DISTINCT uin) login_uins   
    FROM
        tabled
    WHERE
        ftime >= 20121001
        AND ftime <= 20121001
  
例句2SELECT
        COUNT(uin) login_uins
    FROM
        ( select distinct uin from tabled  WHERE
        ftime >= 20121001
        AND ftime <= 20121001   ) subq
  1. 例句1虽然只有1个mr,但是,这个mr却只有1个reduce任务,导致这个reduce任务需要读取和处理大量的数据,这不仅导致执行慢,而且,在如果tabled中的数据量太大,可能导致执行reduce任务的节点down掉。
  2. 例句2先去重,后全局统计,没有像例句1那样明显的瓶颈。所以,请牢记当对某个数据集进行全局count distinct操作时,尽量用例句2的形式。
  3. 在其他情况下,即使有group by,但是group by的维度太低,也可以考虑这种改写方法。也就是说,一定要避免group by的维度太低。

17. join和exists问题

-- NOT EXISTS使用left outer join加 is null实现的:
selectfrom a 
whereand not exists(select 1 from b where a.col1=b.col2 and b.col3=and)

等价于

selectfrom a 
left outer join b 
on a.col1=b.col2 
and b.col3=andwhereand b.col2 is null
 
-- 使用left simi join实现exists:
selectfrom a 
whereand exists(select 1 from b where a.col1=b.col2 and b.col3=and)

等价于

selectfrom a 
left semi join b 
on a.col1=b.col2 
and b.col3=and

18. case when then 判断不同条件进行分组求count

select 
platform
,version
,channel
,count(case when lose_user = '1' then qimei end) as lose_user
,count(case when will_lose = '1' then qimei end) as will_lose_user
fromwhere ds=...
and (lose_user = '1' or will_lose = '1')
group by
platform
,version
,channel

19. 并行执行JOB

set hive.exec.parallel=true;   //打开任务并行执行
set hive.exec.parallel.thread.number=16; //同一个sql允许最大并行度,默认为8。

20. 使用本地MR

set hive.exec.mode.local.auto=true;  //开启本地mr
 
//设置local mr的最大输入数据量,当输入数据量小于这个值的时候会采用local  mr的方式
set hive.exec.mode.local.auto.inputbytes.max=50000000;
 
//设置local mr的最大输入文件个数,当输入文件个数小于这个值的时候会采用local mr的方式
set hive.exec.mode.local.auto.tasks.max=10;
 
当这三个参数同时成立时候,才会采用本地mr

21. 避免数据倾斜

数据倾斜可是性能的一大杀手。

21.1 症状

  • 任务迚度长时间维持在99%(或100%);
  • 查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。
  • 本地读写数据量很大。

21.1 原因

  • key分布不均匀
  • GROUP BY
  • COUNT DISTINCT
  • join

21.1 解决方案

  1. group by

使用Hive对数据做一些类型统计的时候遇到过某种类型的数据量特别多,而其他类型数据的数据量特别少。当按照类型进行group by的时候,会将相同的group by字段的reduce任务需要的数据拉取到同一个节点进行聚合,而当其中每一组的数据量过大时,会出现其他组的计算已经完成而这里还没计算完成,其他节点的一直等待这个节点的任务执行完成,所以会看到一直map 100% reduce 99%的情况。

set hive.map.aggr=true
set hive.groupby.skewindata=true

hive.map.aggr=true 这个配置项代表是否在map端进行聚合
hive.groupby.skwindata=true 当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。

  1. map和reduce优化

当出现小文件过多,需要合并小文件。可以通过set hive.merge.mapfiles=true来解决。

单个文件大小稍稍大于配置的block块的大小,此时需要适当增加map的个数。解决方法:set mapred.map.tasks=个数

文件大小适中,但reduce端计算量非常大,如select id,count(*),sum(case when…),sum(case when…)…需要增加map个数。解决方法:set mapred.map.tasks=个数,set mapred.reduce.tasks=个数

  1. count(distinct)

如果数据量非常大,执行如select a,count(distinct b) from t group by a;类型的SQL时,会出现数据倾斜的问题。
解决方法:使用sum…group by代替。如select a,sum(1) from (select a, b from t group by a,b) group by a;

  1. 大表和一个小表进行join

解决方法:使用mapjoin 将小表加载到内存中。
如:select /*+ MAPJOIN(a) */
    a.c1, b.c1 ,b.c2
     from a join b
     where a.c1 = b.c1;

  1. 关联字段有数据为空
select * from log a 
join users b 
on a.id is not null and a.id = b.id 
union all 
select * from log a 
where a.id is null; 
select * from log a 
left outer join users b 
on 
case when a.user_id is null 
then concat(‘hive’,rand() ) 
else a.user_id end = b.user_id; 

22. 控制Map 和 Reduce的数量

22.1 控制map数量

22.1.1 map数量的计算

  1. 主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);
  2. 假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块),从而产生7个map数
  3. 假设input目录下有3个文件a,b,c,大小分别为10m,20m,130m,那么hadoop会分隔成4个块(10m,20m,128m,2m),从而产生4个map数
  4. 如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成一个块。

22.1.2 是不是map越多越好?

答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

22.1.3 是不是保证每个map处理接近128m的文件块,就高枕无忧了?

答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

22.1.4 如何合并小文件,减少map数?

Select count(1) from popt_tbaccountcopy_mes where pt =2012-07-04;

该任务的inputdir /group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04。共有194个文件,其中很多是远远小于128m的小文件,总大小9G,正常执行会用194个map任务。
Map总共消耗的计算资源: SLOTS_MILLIS_MAPS= 623,020

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

再执行上面的语句,用了74个map任务,map消耗的计算资源:SLOTS_MILLIS_MAPS= 333,500
对于这个简单SQL任务,执行时间上可能差不多,但节省了一半的计算资源。

100000000表示100M,
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;这个参数表示执行前进行小文件合并,
前面三个参数确定合并文件块的大小,大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),进行合并,最终生成了74个块。

22.1.5 如何适当的增加map数?

当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率。

select data_desc,
count(1),
count(distinct id),
sum(case when),
sum(case when),
sum()
from a group by data_desc

如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的,这种情况下,我们要考虑将这一个文件合理的拆分成多个,
这样就可以用多个map任务去完成。

set mapred.reduce.tasks=10;
create table a_1 as
select * from a
distribute by rand(123);

这样会将a表的记录,随机的分散到包含10个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。
每个map任务处理大于12M(几百万记录)的数据,效率肯定会好很多。

看上去,貌似这两种有些矛盾,一个是要合并小文件,一个是要把大文件拆成小文件,这点正是重点需要关注的地方,
根据实际情况,控制map数量需要遵循两个原则:使大数据量利用合适的map数;使单个map任务处理合适的数据量;

22.2 控制reduce数量

22.2.1 Hive怎么确定reduce的个数

reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定:
hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G)
hive.exec.reducers.max(每个任务最大的reduce数,默认为999)
计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1)
即,如果reduce的输入(map的输出)总大小不超过1G,那么只会有一个reduce任务;
如:select pt,count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04′ group by pt;
/group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04 总大小为9G多,因此这句有10个reduce

22.2.2 调整reduce个数的方法

set hive.exec.reducers.bytes.per.reducer=500000000;500M)
select pt,count(1) from popt_tbaccountcopy_mes where pt =2012-07-04group by pt; 这次有20个reduce

set mapred.reduce.tasks = 15;
select pt,count(1) from popt_tbaccountcopy_mes where pt =2012-07-04group by pt;这次有15个reduce

22.2.3 reduce个数是不是越多越好?

同map一样,启动和初始化reduce也会消耗时间和资源;另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题

22.2.4 什么情况下只有一个reduce

很多时候你会发现任务中不管数据量多大,不管你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce任务;
其实只有一个reduce任务的情况,除了数据量小于hive.exec.reducers.bytes.per.reducer参数值的情况外,还有以下原因:
1 没有group by的汇总,比如把select pt,count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04′ group by pt; 写成 select count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04′;
2 用了Order by
3 有笛卡尔积
通常这些情况下,除了找办法来变通和避免,暂时没有什么好的办法,因为这些操作都是全局的,所以hadoop不得不用一个reduce去完成;
同样的,在设置reduce个数的时候也需要考虑这两个原则:使大数据量利用合适的reduce数;使单个reduce任务处理合适的数据量;

23. 中间结果压缩

23.1 中间Lzo,最终Gzip

set mapred.output.compress = true;  
set mapred.output.compression.codec = org.apache.hadoop.io.compress.GzipCodec;  
set mapred.output.compression.type = BLOCK;  
  
set mapred.compress.map.output = true;  
set mapred.map.output.compression.codec = org.apache.hadoop.io.compress.LzoCodec;  
  
  
set hive.exec.compress.output = true;  
set hive.exec.compress.intermediate = true;  
set hive.intermediate.compression.codec = org.apache.hadoop.io.compress.LzoCodec; 

23.2 中间Lzo,最终结果不压缩

set mapred.output.compress = true;  
set mapred.output.compression.codec = org.apache.hadoop.io.compress.LzoCodec;  
set mapred.output.compression.type = BLOCK;  
  
set mapred.compress.map.output = true;  
set mapred.map.output.compression.codec = org.apache.hadoop.io.compress.LzoCodec;  
  
  
set hive.exec.compress.intermediate = true;  
set hive.intermediate.compression.codec = org.apache.hadoop.io.compress.LzoCodec; 

24. 杀手锏

  1. 在MapReduce的WEB界面上,关注Hive Job执行的情况;
  2. 了解HQL -> MapReduce的过程;
  3. HQL优化其实也是MapReduce的优化,作为分布式计算模型,其最核心的地方就是要确保每个节点上分布的数据均匀,才能最大程度发挥它的威力,否则,某一个不均匀的节点就会拖后腿。

25. 参数理解优化整理

25.1 container是什么?

Yarn Container就是一个yarn的java进程, 在Mapreduce中的AM,MapTask,ReduceTask, spark的driver和executor等等都作为Container在Yarn的框架上执行,你可以在RM的网页上看到Container的状态。

25.2 相关参数

  1. Yarn
	(1) yarn.scheduler.minimum-allocation-mb 最小容器内存,默认1024M
	(2) yarn.scheduler.maximum-allocation-mb 最大容器内存,默认8192M
	(3) yarn.nodemanager.vmem-pmem-ratio 物理内存与虚拟内存比值,默认2.1,即为使用1G物理内存可以使用2.1G虚拟内存,生产环境中一般会调整大一些,具体虚拟内存分配由操作系统执行,在此不再赘述
	(4) yarn.nodemanager.resource.memory-mb 可以分配给container的物理内存数量,默认8192M
	(5) yarn.scheduler.increment-allocation-mb container内存增量,默认1024M
  1. MapReduce
(1) mapreduce.{map|reduce}.java.opts
(2) mapreduce.{map|reduce}.memory.mb

25.3 讲解

1. Yarn的ResourceManger(简称RM)通过逻辑上的队列分配内存,CPU等资源给application,默认情况下RM允许最大AM申请Container资源为8192MB(“yarn.scheduler.maximum-allocation-mb“),默认情况下的最小分配资源为1024M(“yarn.scheduler.minimum-allocation-mb“),如果参数中需要的资源在此范围之外,在任务submit的时候会被直接拒绝掉

2. AM只能以增量 ("yarn.scheduler.minimum-allocation-mb") + ("yarn.scheduler.increment-allocation-mb") 规整每个task需要的内存,并且申请的内存只能在(”yarn.scheduler.minimum-allocation-mb“)和(“yarn.scheduler.maximum-allocation-mb“) 的范围内向RM申请资源。用mr任务举例,再默认情况下,比如只修改了map task配置需要1536M内存,但实际分配出来map task占用2G内存,原因在于 container最小内存1024M < 1560M < container 最小内存为1024M + container内存增量1024M, 故分配2G内存。

25.4 图示

在这里插入图片描述

从上面的图可以看出map,reduce,AM container的JVM,“JVM”矩形代表服务进程,“Max heap”,“Max virtual”矩形代表NodeManager对JVM进程的最大内存和虚拟内存的限制。

以map container内存分配(“mapreduce.map.memory.mb“)设置为1536M为例,AM将会为container向RM请求2048mb的内存资源(原因见上)。这是一种逻辑上的分配,这个值被NodeManager用来监控改进程内存资源的使用率,如果Task进程树(包括task启动子进程占用的内存,这样可以解决hadoop streaming任务内存跑飞的情况,实际上是对内存使用的一种软限制,至于为什么没有使用Cgroups做限制,大家可以自行查阅资料)的使用超过了2048MB,NM将会把这个task给杀掉。

mapreduce.map.java.opts和mapreduce.map.memory.mb区别:JVM进程跑在container中,mapreduce.{map|reduce}.java.opts能够通过Xmx设置JVM最大的heap的使用,一般设置为0.75倍的mapreduce.{map|reduce}.memory.mb ,因为需要为java code,非JVM内存使用等预留些空间,同理:spark executor在申请内存是也会为堆外内存预留一些空间,参数由spark.yarn.executor.memoryOverhead 控制,算法为 max(384m, 0.07*spark.executor.memory) **

当一个mapreduce job完成时,你将会看到一系列的计数器被打印出来,下面的三个计数器展示了多少物理内存和虚拟内存被分配
Physical memory (bytes) snapshot=21850116096
Virtual memory (bytes) snapshot=40047247360
Total committed heap usage (bytes)=22630105088

25.5 虚拟内存

默认的(“yarn.nodemanager.vmem-pmem-ratio“)设置为2.1,意味则map container或者reduce container分配的虚拟内存超过2.1倍的(“mapreduce.reduce.memory.mb“)或(“mapreduce.map.memory.mb“)就会被NM给KILL掉,如果 (“mapreduce.map.memory.mb”) 被设置为1536M那么总的虚拟内存为2.1*1536=3225.6MB

当container的内存超出要求的,log将会打印信息:
Current usage: 2.1gb of 2.0gb physical memory used; 1.6gb of 3.15gb virtual memory used. Killing container.

25.6 内存调优

1、Mapper/Reducer阶段JVM内存溢出(一般都是堆)

	1)JVM堆(Heap)内存溢出:堆内存不足时,一般会抛出如下异常:
	第一种:“java.lang.OutOfMemoryError:” GC overhead limit exceeded;
	第二种:“Error: Java heapspace”异常信息;
	第三种:“running beyondphysical memory limits.Current usage: 4.3 GB of 4.3 GBphysical memoryused; 7.4 GB of 13.2 GB virtual memory used. Killing container”。

	2) 栈内存溢出:抛出异常为:java.lang.StackOverflflowError
	常会出现在SQL中(SQL语句中条件组合太多,被解析成为不断的递归调用),或MR代码中有递归调用。这种深度的递归调用在栈中方法调用链条太长导致的。出现这种错误一般说明程序写的有问题。

2、MRAppMaster内存不足

	如果作业的输入的数据很大,导致产生了大量的Mapper和Reducer数量,致使MRAppMaster(当前作业的管理者)的压力很大,最终导致MRAppMaster内存不足,作业跑了一般出现了OOM信息
	异常信息为:
	Exception: java.lang.OutOfMemoryError thrown from theUncaughtExceptionHandler in thread
	"Socket Reader #1 for port 30703
	Halting due to Out Of Memory Error...
	Halting due to Out Of Memory Error...
	Halting due to Out Of Memory Error...

3、非JVM内存溢出

	异常信息一般为:java.lang.OutOfMemoryError:Direct buffffer memory
	自己申请使用操作系统的内存,没有控制好,出现了内存泄露,导致的内存溢出。错误解决参数调优

	
	
1、Mapper/Reducer阶段JVM堆内存溢出参数调优

	目前MapReduce主要通过两个组参数去控制内存:(将如下参数调大)
	
	Maper:
	mapreduce.map.java.opts=-Xmx2048m(默认参数,表示jvm堆内存,注意是mapreduce不是mapred)
	mapreduce.map.memory.mb=2304(container的内存)

	Reducer:
	mapreduce.reduce.java.opts=-=-Xmx2048m(默认参数,表示jvm堆内存)
	mapreduce.reduce.memory.mb=2304(container的内存)

	注意:因为在yarn container这种模式下,map/reduce task是运行在Container之中的,所以上面提到的mapreduce.map(reduce).memory.mb大小都大于mapreduce.map(reduce).java.opts值的大小。mapreduce.{map|reduce}.java.opts能够通过Xmx设置JVM最大的heap的使用,一般设置为0.75倍的memory.mb,因为需要为java code等预留些空间


2、MRAppMaster:

	yarn.app.mapreduce.am.command-opts=-Xmx1024m(默认参数,表示jvm堆内存)
	yarn.app.mapreduce.am.resource.mb=1536(container的内存)
	
	注意在Hive ETL里面,按照如下方式设置:
	set mapreduce.map.child.java.opts="-Xmx3072m"(注:-Xmx设置时一定要用引号,不加引号各种错误)
	set mapreduce.map.memory.mb=3288

	或

	set mapreduce.reduce.child.java.opts="xxx"
	set mapreduce.reduce.memory.mb=xxx

	涉及YARN参数:

	•yarn.scheduler.minimum-allocation-mb (最小分配单位1024M)
	•yarn.scheduler.maximum-allocation-mb (8192M
	•yarn.nodemanager.vmem-pmem-ratio (虚拟内存和物理内存之间的比率默认 2.1)
	•yarn.nodemanager.resource.memory.mb

	Yarn的ResourceManger(简称RM)通过逻辑上的队列分配内存,CPU等资源给application,默认情况下RM允许最大AM申请Container资源为8192MB(“yarn.scheduler.maximum-allocation-mb“),默认情况下的最小分配资源为1024M(“yarn.scheduler.minimum-allocation-mb“),AM只能以增量(”yarn.scheduler.minimum-allocation-mb“)和不会超过(“yarn.scheduler.maximum-allocationmb“)的值去向RM申请资源,AM负责将(“mapreduce.map.memory.mb“)和

	(“mapreduce.reduce.memory.mb“)的值规整到能被(“yarn.scheduler.minimum-allocation-mb“)整除,RM会拒绝申请内存超过8192MB和不能被1024MB整除的资源请求。(不同配置会有不同)

25.7 mapred.child.java.opts

mapred.child.java.opts
这个参数是配置每个map或reduce使用的内存数量。默认的是200M。

mapred.child.java.opts就是设定jvm的参数之一,在新版本中已经标准为过期,取而代之的是区分Map Task 和Reduce Task 的jvm opts , mapred.map.child.java.opts和mapred.reduce.child.java.opts(默认值为-Xmx200m)
当用户在不设置该值情况下,会以最大1G jvm heap size启动task,有可能导致OutOfMemory,所以最简单的做法就是设大参数,并且由于这个值不是final,所以用户可以在自己的mapred-site.xml中可以覆盖默认值

其实在构造JVM Args的过程中,是有另外一个admin参考可以覆盖用户端设置的
mapreduce.admin.map.child.java.opts   mapreduce.admin.reduce.child.java.opts
在mapred-site.xml中加上如下配置:
<property>
   <name>mapreduce.admin.map.child.java.opts</name>
   <value>-Xmx1024m</value>
</property>
<property>
    <name>mapreduce.admin.reduce.child.java.opts</name>
    <value>-Xmx5120m</value>
</property>

mapred.child.java.opts设置成多大比较合适:

这个参数是配置每个map或reduce使用的内存数量,默认是200m,一般情况下,该值设置为 总内存/并发数量(=核数)

mapred.map.child.java.opts和mapreduce.map.memeory.mb的区别:

mapreduce.map.memory.mb是向RM申请的内存资源大小,这些资源可用用于各种程序语言编写的程序, mapred.map.child.java.opts 一般只用于配置JVM参数

25.8 mapreduce优化

优化(1)资源相关参数:
以下参数是在自己的 MapReduce 应用程序中配置就可以生效

mapreduce.map.memory.mb: 一个 Map Task 可使用的内存上限(单位:MB),默认为 1024。如果 Map Task 实际使用的资源量超过该值,则会被强制杀死。
mapreduce.reduce.memory.mb: 一个 Reduce Task 可使用的资源上限(单位:MB),默认为 1024。如果 Reduce Task 实际使用的资源量超过该值,则会被强制杀死。
mapreduce.map.cpu.vcores: 每个 Maptask 可用的最多 cpu core 数目, 默认值: 1
mapreduce.reduce.cpu.vcores: 每个 Reducetask 可用最多 cpu core 数目默认值: 1
mapreduce.map.java.opts: Map Task 的 JVM 参数,你可以在此配置默认的 java heap size 等参数, 例如:“-Xmx1024m -verbose:gc -Xloggc:/tmp/@taskid@.gc”
(@taskid@会被 Hadoop 框架自动换为相应的 taskid), 默认值: “”
mapreduce.reduce.java.opts: Reduce Task 的 JVM 参数,你可以在此配置默认的 java heap size 等参数, 例如:“-Xmx1024m -verbose:gc -Xloggc:/tmp/@taskid@.gc”, 默认值: “”


以下在 yarn 启动之前就配置在服务器的配置文件中才能生效
yarn.scheduler.minimum-allocation-mb RM 中每个容器请求的最小配置,以 MB 为单位,默认 1024。
yarn.scheduler.maximum-allocation-mb RM 中每个容器请求的最大分配,以 MB 为单位,默认 8192。
yarn.scheduler.minimum-allocation-vcores 1
yarn.scheduler.maximum-allocation-vcores 32
yarn.nodemanager.resource.memory-mb 表示该节点上YARN可使用的物理内存总量,默认是 8192(MB),注意,如果你的节点内存资源不够 8GB,则需要调减小这个值,而 YARN不会智能的探测节点的物理内存总量。


shuffle 性能优化的关键参数,应在 yarn 启动之前就配置好
mapreduce.task.io.sort.mb 100 shuffle 的环形缓冲区大小,默认 100m
mapreduce.map.sort.spill.percent 0.8 环形缓冲区溢出的阈值,默认 80%

 

 
优化(2)容错相关参数:
mapreduce.map.maxattempts: 每个 Map Task 最大重试次数,一旦重试参数超过该值,则认为 Map Task 运行失败,默认值:4。
mapreduce.reduce.maxattempts: 每个Reduce Task最大重试次数,一旦重试参数超过该值,则认为 Map Task 运行失败,默认值:4。
mapreduce.map.failures.maxpercent: 当失败的 Map Task 失败比例超过该值,整个作业则失败,默认值为 0. 如果你的应用程序允许丢弃部分输入数据,则该该值设为一个大于 0 的值,比如 5,表示如果有低于 5%的 Map Task 失败(如果一个 Map Task 重试次数超过mapreduce.map.maxattempts,则认为这个 Map Task 失败,其对应的输入数据将不会产生任何结果),整个作业扔认为成功。
mapreduce.reduce.failures.maxpercent: 当失败的 Reduce Task 失败比例超过该值为,整个作业则失败,默认值为 0.
mapreduce.task.timeout:如果一个task在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该 task 处于 block 状态,可能是临时卡住,也许永远会卡住。为了防止因为用户程序永远 block 不退出,则强制设置了一个超时时间(单位毫秒),默认是600000,值为 0 将禁用超时。

 


优化(3)效率跟稳定性参数(任务的推测执行):
Straggle(掉队者)是指那些跑的很慢但最终会成功完成的任务。一个掉队的Map任务会阻止Reduce任务开始执行。

Hadoop不能自动纠正掉队任务,但是可以识别那些跑的比较慢的任务,然后它会产生另一个等效的任务作为备份,并使用首先完成的那个任务的结果,此时另外一个任务则会被要求停止执行。这种技术称为推测执行(speculative execution)。

默认使用推测执行。
属性                                                                                           描述
mapreduce.map.speculative                                                     控制Map任务的推测执行(默认true)
mapreduce.reduce.speculative                                                 控制Reduce任务的推测执行(默认true)
mapreduce.job.speculative.speculativecap                              推测执行功能的任务能够占总任务数量的比例(默认0.1,范围0~1)
mapreduce.job.speculative.slownodethreshold                        判断某个TaskTracker是否适合启动某个task的speculative task(默认1)
mapreduce.job.speculative.slowtaskthreshold                         判断某个task是否可以启动speculative task(默认1)
mapreduce.input.fileinputformat.split.minsize                          FileInputFormat做切片时最小切片大小,默认 1。

mapreduce.input.fileinputformat.split.maxsize                         FileInputFormat做切片时最大切片大小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值