大数据学习_Hadoop_调优及二次开发示例

1 Job执行三原则

  • 充分利用集群资源
  • reduce阶段尽量放在一轮
  • 每个task的执行时间要合理

1.1 原则一 充分利用集群资源

Job运行时,尽量让所有的节点都有任务处理,这样能尽量保证集群资源被充分利用,任务的并发度达到最大。可以通过调整处理的数据量大小,以及调整map和reduce个数来实现。

  • Reduce个数的控制使用“mapreduce.job.reduces”
  • Map个数取决于使用了哪种InputFormat,默认的TextFileInputFormat将根据block的个数来分配map数(一个block一个map)。

1.2 原则二 ReduceTask并发调整

努力避免出现以下场景:

  • 观察Job如果大多数ReduceTask在第一轮运行完后,剩下很少甚至一个ReduceTask刚开始运行。这种情况下,这个ReduceTask的执行时间将决定了该job的运行时间。可以考虑将reduce个数减少。
  • 观察Job的执行情况如果是MapTask运行完成后,只有个别节点有ReduceTask在运行。这时候集群资源没有得到充分利用,需要增加Reduce的并行度以便每个节点都有任务处理。

1.3 原则三 Task执行时间要合理

一个job中,每个MapTask或ReduceTask的执行时间只有几秒钟,这就意味着这个job的大部分时间都消耗在task的调度和进程启停上了,因此可以考虑增加每个task处理的数据大小。建议一个task处理时间为1分钟。

2 Shuffle调优

Shuffle阶段是MapReduce性能的关键部分,包括了从MapTaskask将中间数据写到磁盘一直到ReduceTask拷贝数据并最终放到Reduce函数的全部过程。这一块Hadoop提供了大量的调优参数。

2.1 Map阶段

  1. 判断Map内存使用
    判断Map分配的内存是否够用,可以查看运行完成的job的Counters中(历史服务器),对应的task是否发生过多次GC,以及GC时间占总task运行时间之比。通常,GC时间不应超过task运行时间的10%,即GC time elapsed(ms)/CPU time spent (ms)<10%。
    在这里插入图片描述
    Map需要的内存还需要随着环形缓冲区的调大而对应调整。可以通过如下参数进行调整。
    mapreduce.map.memory.mb
    Ma需要的CPU核数可以通过如下参数调整
    mapreduce.map.cpu.vcores
    可以看到内存默认是1G,CPU默认是1核。
    如果集群资源充足建议调整:
    mapreduce.map.memory.mb=3G(默认1G)mapreduce.map.cpu.vcores=1(默认也是1)
  • 环形缓冲区
    Map方法执行后首先把数据写入环形缓冲区,为什么MR框架选择先写内存而不是直接写磁盘?这样的目的主要是为了减少磁盘i/o
    1.环形缓冲默认100M(mapreduce.task.io.sort.mb),当到达80%(mapreduce.map.sort.spill.percent)时就会溢写磁盘。
    2.每达到80%都会重写溢写到一个新的文件。

当集群内存资源充足,考虑增大mapreduce.task.io.sort.mb提高溢写的效率,而且会减少中间结果的文件数量。
建议:

  • 调整mapreduce.task.io.sort.mb=512M,降低溢写的次数,较少文件的数量。
  • 当文件溢写完后,会对这些文件进行合并,默认每次合10(mapreduce.task.io.sort.factor)个溢写的文件,建议调整mapreduce.task.io.sort.factor=64。这样可以提高合并的并行度,减少合并的次数,降低对磁盘操作的次数。
  1. Combiner
    在Map阶段,有一个可选过程(预聚合),将同一个key值的中间结果合并(wc案例中有使用),叫做Combiner。(一般将reduce类设置为combiner即可)。通过Combiner,一般情况下可以显著减少Map输出的中间结果,从而减少shuffle过程的网络带宽占用。
    建议:
    在不影响最终结果的情况下,加上Combiner。

2.2 Copy阶段

  • 对Map的中间结果进行压缩,当数据量大时,会显著减少网络传输的数据量
  • 但是也因为多了压缩和解压,带来了更多的CPU消耗。因此需要做好权衡。当任务属于网络瓶颈类型时,压缩Map中间结果效果明显。
  • 在实际经验中Hadoop的运行的瓶颈一般都是IO而不是CPU,压缩一般可以10倍的减少IO操作

2.3 Reduce阶段

  1. Reduce资源
    每个Reduce资源
mapreduce.reduce.memory.mb=5G(默认1G)
mapreduce.reduce.cpu.vcores=1(默认为1)。
  1. Copy
    ReduceTask在copy的过程中默认使用5(mapreduce.reduce.shuffle.parallelcopies参数控制)个并行度进行复制数据。
    该值在实际服务器上比较小,建议调整为50-100.
  2. 溢写归并
    • Copy过来的数据会先放入内存缓冲区中,然后当使用内存达到一定量的时候spill磁盘。这里的缓冲区大小要比map端的更为灵活,它基于JVM的heap size设置。这个内存大小的控制是通过mapreduce.reduce.shuffle.input.buffer.percent(default 0.7)控制的。
    • shuffile在reduce内存中的数据最多使用内存量为:0.7 × maxHeap of reduce task,内存到磁盘merge的启动可以通过mapreduce.reduce.shuffle.merge.percent(default0.66)配置。
    • copy完成后,reduce进入归并排序阶段,合并因子默认为10(mapreduce.task.io.sort.factor参数控制),如
      果map输出很多,则需要合并很多趟,所以可以提高此参数来减少合并次数。

3 Job调优

3.1.推测执行

集群规模很大时(几百上千台节点的集群),个别机器出现软硬件故障的概率就变大了,并且会因此延长整个任务的执行时间推测执行通过将一个task分给多台机器跑,取先运行完的那个,会很好的解决这个问题。对于小集群,可以将这个功能关闭。
建议:
- 大型集群建议开启,小集群建议关闭!
- 集群的推测执行都是关闭的。在需要推测执行的作业执行的时候开启

3.2 Slow Start

MapReduce的AM在申请资源的时候,会一次性申请所有的Map资源,延后申请reduce的资源,这样就能达到先执行完大部分Map再执行Reduce的目的。
mapreduce.job.reduce.slowstart.completedmaps
当多少占比的Map执行完后开始执行Reduce。默认5%的Map跑完后开始起Reduce。如果想要Map完全结束后执行Reduce调整该值为1

3.3 小文件优化

- HDFS:hadoop的存储每个文件都会在NameNode上记录元数据,如果同样大小的文件,文件很小的话,就会产生很多文件,造成NameNode的压力。
- MR:Mapreduce中一个map默认处理一个分片或者一个小文件,如果map的启动时间都比数据处理的时间还要长,那么就会造成性能低,而且在map端溢写磁盘的时候每一个map最终会产生reduce数量个数的中间结果,如果map数量特别多,就会造成临时文件很多,而且在reduce拉取数据的时候增加磁盘的IO。

那么如何处理小文件?
- 从源头解决,尽量在HDFS上不存储小文件,也就是数据上传HDFS的时候就合并小文件
- 通过运行MR程序合并HDFS上已经存在的小文件
- MR计算的时候可以使用CombineTextInputFormat来降低MapTask并行度

3.4 数据倾斜

- MR是一个并行处理的任务,整个Job花费的时间是作业中所有Task最慢的那个了。

为什么会这样呢?为什么会有的Task快有的Task慢?
- 数据倾斜,每个Reduce处理的数据量不是同一个级别的,所有数据量少的Task已经跑完了,数据量大的Task则需要更多时间。
- 有可能就是某些作业所在的NodeManager有问题或者container有问题,导致作业执行缓慢。
如何解决数据倾斜的问题呢?
- 默认的是hash算法进行分区,我们可以尝试自定义分区,修改分区实现逻辑,结合业务特点,使得每个分区数据基本平衡
- 可以尝试修改分区的键,让其符合hash分区,并且使得最后的分区平衡,比如在key前加随机数n-key。
- 抽取导致倾斜的key对应的数据单独处理。

如果不是数据倾斜带来的问题,而是节点服务有问题造成某些map和reduce执行缓慢呢?
使用推测执行找个其他的节点重启一样的任务竞争,谁快谁为准。推测执行时以空间换时间的优化。会带来集群资源的浪费,会给集群增加压力。

4 YARN调优

4.1 NM配置

  • 可用内存
    刨除分配给操作系统、其他服务的内存外,剩余的资源应尽量分配给YARN。
    默认情况下,Map或Reduce container会使用1个虚拟CPU内核和1024MB内存,ApplicationMaster使用1536MB内存。
yarn.nodemanager.resource.memory-mb 默认是8192
  • CPU虚拟核数
    建议将此配置设定在逻辑核数的1.5~2倍之间。如果CPU的计算能力要求不高,可以配置为2倍的逻辑CPU。
yarn.nodemanager.resource.cpu-vcores
该节点上YARN可使用的虚拟CPU个数,默认是8。
目前推荐将该值设值为逻辑CPU核数的1.5~2倍之间

4.2 ontainer启动模式

YARN的NodeManager提供2种Container的启动模式。

yarn.nodemanager.container-executor.class
  • 设置为“org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor”,则每次启动container将会启动一个线程来实现资源本地化。
    该模式下,启动时间较短,但无法做到资源(CPU、内存)隔离。
  • 设置为“org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor” ,则每次启动container都会启动一个JVM进程来实现资源本地化。
    该模式下,启动时间较长,但可以提供较好的资源(CPU、内存)隔离能力。

4.3 AM调优

运行的一个大任务,map总数达到了上万的规模,任务失败,发现是ApplicationMaster(以下简称AM)反应缓慢,最终超时失败。
失败原因是Task数量变多时,AM管理的对象也线性增长,因此就需要更多的内存来管理。AM默认分配的内存大小是1.5GB。
建议:
任务数量多时增大AM内存。

yarn.app.mapreduce.am.resource.mb

5 Namenode Full GC

在这里插入图片描述

  • JVM内存划分为堆内存和非堆内存,堆内存分为年轻代(Young Generation)、老年代(OldGeneration),非堆内存就一个永久代(Permanent Generation)。
  • 年轻代又分为Eden和Survivor区。Survivor区由FromSpace和ToSpace组成。Eden区占大容量,Survivor两个区占小容量,默认比例是8:1:1。
  • 堆内存用途:存放的是对象,垃圾收集器就是收集这些对象,然后根据GC算法回收。
  • 非堆内存用途:永久代,也称为方法区,存储程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等。
  • JDK1.8版本废弃了永久代,替代的是元空间(MetaSpace),元空间与永久代上类似,都是方法区的实现,他们最大区别是:元空间并不在JVM中,而是使用本地内存。

5.1 对象分代

  • 新生成的对象首先放到年轻代Eden区,
  • 当Eden空间满了,触发Minor GC,存活下来的对象移动到Survivor0区,
  • Survivor0区满后触发执行Minor GC,Survivor0区存活对象移动到Suvivor1区,这样保证了一段时间内总有一个survivor区为空。
  • 经过多次Minor GC仍然存活的对象移动到老年代。
  • 老年代存储长期存活的对象,占满时会触发Major GC(Full GC),GC期间会停止所有线程等待GC完成,所以对响应要求高的应用尽量减少发生Major GC,避免响应超时。
  • Minor GC : 清理年轻代 Major GC(Full GC) : 清理老年代,清理整个堆空间,会停止应用所有线程。

5.2 Jstat

查看当前jvm内存使用以及垃圾回收情况
jstat -gc -t 7653 1s #显示pid是7653的垃圾回收堆的行为统计
在这里插入图片描述
结果解释:

#C即Capacity 总容量,U即Used 已使用的容量
S0C: 当前survivor0区容量(kB)。
S1C: 当前survivor1区容量(kB)。
S0U: survivor0区已使用的容量(KB)
S1U: survivor1区已使用的容量(KB)
EC: Eden区的总容量(KB)
EU: 当前Eden区已使用的容量(KB)
OC: Old空间容量(kB)。
OU: Old区已使用的容量(KB)
MC: Metaspace空间容量(KB)
MU: Metacspace使用量(KB)
CCSC: 压缩类空间容量(kB)。
CCSU: 压缩类空间使用(kB)。
YGC: 新生代垃圾回收次数
YGCT: 新生代垃圾回收时间
FGC: 老年代 full GC垃圾回收次数
FGCT: 老年代垃圾回收时间
GCT: 垃圾回收总消耗时间

开启HDFS GC详细日志输出
编辑hadoop-env.sh

编辑hadoop-env.sh

增加JMX配置打印详细GC信息
指定一个日志输出目录;注释掉之前的ops
增加新的打印配置

6 Hadoop二次开发环境搭建

查看内存使用:

free -m

清理内存:

echo 1 >>/proc/sys/vm/drop_caches
echo 2 >>/proc/sys/vm/drop_caches
echo 3 >>/proc/sys/vm/drop_caches
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值