Hadoop性能调优、YARN的内存和CPU配置

转自: https://blog.csdn.net/tototuzuoquan/article/details/80671128html

 

转: 
https://blog.csdn.net/dehu_zhou/article/details/52808752 
https://blog.csdn.net/dxl342/article/details/52840455java

Hadoop为用户做业提供了多种可配置的参数,以容许用户根据做业特色调整这些参数值使做业运行效率达到最优。node

一 应用程序编写规范

1.设置Combiner

对于一大批MapReduce程序,若是能够设置一个Combiner,那么对于提升做业性能是十分有帮助的。Combiner可减小Map Task中间输出的结果,从而减小各个Reduce Task的远程拷贝数据量,最终表现为Map Task和Reduce Task执行时间缩短。python

2. 选择合理的Writable类型

在MapReduce模型中,Map Task和Reduce Task的输入和输出类型均为Writable。Hadoop自己已经提供了不少Writable实现,包括IntWritable、FloatWritable。为应用程序处理的数据选择合适的Writable类型可大大提高性能。好比处理整数类型数据时,直接采用IntWritable比先以Text类型读入在转换为整数类型要高效。若是输出整数的大部分可用一个或两个字节保存,那么直接采用VIntWritable或者VLongWritable,它们采用了变长整型的编码方式,能够大大减小输出数据量。算法

二 做业级别参数调优

1.规划合理的任务数目

在Hadoop中,每一个Map Task处理一个Input Split。Input Split的划分方式是由用户自定义的InputFormat决定的,默认状况下,有如下三个参数决定。 
mapred.min.split.size :Input Split的最小值 默认值1 
mapred.max.split.szie: Input Split的最大值 
dfs.block.size:HDFS 中一个block大小 默认值64MB 
golsize:它是用户指望的Input Split数目=totalSize/numSplits ,其中totalSize为文件的总大小;numSplits为用户设定的Map Task个数,默认状况下是1. 
splitSize = max{minSize,min{goalSize,blockSize}} 若是想让InputSize尺寸大于block尺寸,直接增大配置参数mpared.min.split.size便可。缓存

2.增长输入文件的副本数

若是一个做业并行执行的任务数目很是多,那么这些任务共同的输入文件可能成为瓶颈。为防止多个任务并行读取一个文件内容形成瓶颈,用户可根据须要增长输入文件的副本数目。网络

3.启动推测执行机制

推测执行是Hadoop对“拖后腿”的任务的一种优化机制,当一个做业的某些任务运行速度明显慢于同做业的其余任务时,Hadoop会在另外一个节点上为“慢任务”启动一个备份任务,这样两个任务同时处理一份数据,而Hadoop最终会将优先完成的那个任务的结果做为最终结果,并将另外一个任务杀掉。多线程

4.设置失败容忍度

Hadoop运行设置任务级别和做业级别的失败容忍度。做业级别的失败容忍度是指Hadoop容许每一个做业有必定比例的任务运行失败,这部分任务对应的输入数据将被忽略; 
任务级别的失败容忍度是指Hadoop容许任务失败后再在另外节点上尝试运行,若是一个任务通过若干次尝试运行后仍然运行失败,那么Hadoop才会最终认为该任务运行失败。 
用户应该根据应用程序的特色设置合理的失败容忍度,以尽快让做业运行完成和避免不必的资源浪费。架构

5.适当打开JVM重用功能

为了实现任务隔离,Hadoop将每一个任务放到一个单独的JVM中执行,而对于执行时间较短的任务,JVM启动和关闭的时间将占用很大比例时间,为此,用户能够启用JVM重用功能,这样一个JVM可连续启动多个同类型的任务。并发

6.设置任务超时时间

若是一个任务在必定的时间内未汇报进度,则TaskTracker会主动将其杀死,从而在另外一个节点上从新启动执行。用户可根据实际须要配置任务超时时间。

7.合理使用DistributedCache

通常状况下,获得外部文件有两种方法:一种是外部文件与应用程序jar包一块儿放到客户端,当提交做业时由客户端上传到HDFS的一个目录下,而后经过Distributed Cache分发到各个节点上;另外一种方法是事先将外部文件直接放到HDFS上,从效率上讲,第二种方法更高效。第二种方法不只节省了客户端上传文件的时间,还隐含着告诉DistributedCache:”请将文件下载到各个节点的pubic级别共享目录中”,这样,后续全部的做业可重用已经下载好的文件,没必要重复下载。

8.跳过坏记录

Hadoop为用户提供了跳过坏记录的功能,当一条或几条坏数据记录致使任务运行失败时,Hadoop可自动识别并跳过这些坏记录。

9.提升做业优先级

全部Hadoop做业调度器进行任务调度时均会考虑做业优先级这一因素。做业的优先级越高,它可以获取的资源(slot数目)也越多。Hadoop提供了5种做业优先级,分别为VERY_HIGH、 HIGH、 NORMAL、 LOW、 VERY_LOW。 
注:在生产环境中,管理员已经按照做业重要程度对做业进行了分级,不一样重要程度的做业容许配置的优先级不一样,用户能够擅自进行调整。

10.合理控制Reduce Task的启动时机

若是Reduce Task启动过早,则可能因为Reduce Task长时间占用Reduce slot资源形成”slot Hoarding”现象,从而下降资源利用率;反之,若是Reduce Task启动过晚,则会致使Reduce Task获取资源延迟,增长了做业的运行时间。

三 任务级别参数调优

hadoop任务级别参数调优分两个方面: Map Task和Reduce Task。

1.Map Task调优

map运行阶段分为:Read、Map、Collect、Spill、Merge五个阶段。
map 任务执行会产生中间数据,但这些中间结果并无直接IO到磁盘上,而是先存储在缓存(buffer)中,并在缓存中进行一些预排序来优化整个map的性能,存储map中间数据的缓存默认大小为100M,由io.sort.mb 参数指定。这个大小能够根据须要调整。当map任务产生了很是大的中间数据时能够适当调大该参数,使缓存能容纳更多的map中间数据,而不至于大频率的IO磁盘,当系统性能的瓶颈在磁盘IO的速度上,能够适当的调大此参数来减小频繁的IO带来的性能障碍。
因为map任务运行时中间结果首先存储在缓存中,默认当缓存的使用量达到80%(或0.8)的时候就开始写入磁盘,这个过程叫作spill(也叫溢出),进行spill的缓存大小能够经过io.sort.spill.percent 参数调整,这个参数能够影响spill的频率。进而能够影响IO的频率。
当map任务计算成功完成以后,若是map任务有输出,则会产生多个spill。接下来map必须将些spill进行合并,这个过程叫作merge, merge过程是并行处理spill的,每次并行多少个spill是由参数io.sort.factor指定的默认为10个。可是当spill的数量很是大的时候,merge一次并行运行的spill仍然为10个,这样仍然会频繁的IO处理,所以适当的调大每次并行处理的spill数有利于减小merge数所以能够影响map的性能。
当map输出中间结果的时候也能够配置压缩。
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述

2. Reduce Task调优

reduce 运行阶段分为shuflle(copy) merge sort   reduce write五个阶段。
shuffle 阶段为reduce 全面拷贝map任务成功结束以后产生的中间结果,若是上面map任务采用了压缩的方式,那么reduce 将map任务中间结果拷贝过来后首先进行解压缩,这一切是在reduce的缓存中作的,固然也会占用一部分cpu。为了优化reduce的执行时间,reduce也不是等到全部的map数据都拷贝过来的时候才开始运行reduce任务,而是当job执行完第一个map任务时开始运行的。reduce 在shuffle阶段 其实是从不一样的而且已经完成的map上去下载属于本身的数据,因为map任务数不少,全部这个copy过程是并行的,既同时有许多个reduce取拷贝map,这个并行的线程是经过mapred.reduce.parallel.copies 参数指定,默认为5个,也就是说不管map的任务数是多少个,默认状况下一次只能有5个reduce的线程去拷贝map任务的执行结果。因此当map任务数不少的状况下能够适当的调整该参数,这样可让reduce快速的得到运行数据来完成任务。
reduce线程在下载map数据的时候也可能由于各类各样的缘由(网络缘由、系统缘由等),存储该map数据所在的datannode 发生了故障,这种状况下reduce任务将得不到该datanode上的数据了,同时该 download thread 会尝试从别的datanode下载,能够经过mapred.reduce.copy.backoff (默认为30秒)来调整下载线程的下载时间,若是网络很差的集群能够经过增长该参数的值来增长下载时间,以避免由于下载时间过长reduce将该线程判断为下载失败。
reduce 下载线程在map结果下载到本地时,因为是多线程并行下载,因此也须要对下载回来的数据进行merge,因此map阶段设置的io.sort.factor 也一样会影响这个reduce的。
同map同样 该缓冲区大小也不是等到彻底被占满的时候才写入磁盘而是默认当完成0.66的时候就开始写磁盘操做,该参数是经过mapred.job.shuffle.merge.percent 指定的。
当reduce 开始进行计算的时候经过mapred.job.reduce.input.buffer.percent 来指定须要多少的内存百分比来做为reduce读已经sort好的数据的buffer百分比,该值默认为0。Hadoop假设用户的reduce()函数须要全部的JVM内存,所以执行reduce()函数前要释放全部内存。若是设置了该值,可将部分文件保存在内存中(没必要写到磁盘上)。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述

总之,Map Task和Reduce Task调优的一个原则就是减小数据的传输量、尽可能使用内存、减小磁盘IO的次数、增大任务并行数,除此以外还有根据本身集群及网络的实际状况来调优。
  • 1

三 管理员角度调优

管理员负责为用户做业提供一个高效的运行环境。管理员须要从全局出发,经过调整一些关键参数提升系统的吞吐率和性能。整体上来看,管理员需从硬件选择、操做系统参数调优、JVM参数调优和Hadoop参数调优等四个角度入手,为Hadoop用户提供一个高效的做业运行环境。
  • 1

硬件选择 
Hadoop自身架构的基本特色决定了其硬件配置的选项。Hadoop采用了Master/Slave架构,其中,master维护了全局元数据信息,重要性远远大于slave。在较低Hadoop版本中,master存在单点故障问题,所以,master的配置应远远好于各个slave。

操做系统参数调优

1.增大同时打开的文件描述符和网络链接上限

使用ulimit命令将容许同时打开的文件描述符数目上限增大至一个合适的值。同时调整内核参数net.core.somaxconn网络链接数目至一个足够大的值。

补充:net.core.somaxconn的做用 
net.core.somaxconn是Linux中的一个kernel参数,表示socket监听(listen)的backlog上限。什么是backlog呢?backlog就是socket的监听队列,当一个请求(request)还没有被处理或创建时,它会进入backlog。而socket server能够一次性处理backlog中的全部请求,处理后的请求再也不位于监听队列中。当server处理请求较慢,以致于监听队列被填满后,新来的请求会被拒绝。在Hadoop 1.0中,参数ipc.server.listen.queue.size控制了服务端socket的监听队列长度,即backlog长度,默认值是128。而Linux的参数net.core.somaxconn默认值一样为128。当服务端繁忙时,如NameNode或JobTracker,128是远远不够的。这样就须要增大backlog,例如咱们的3000台集群就将ipc.server.listen.queue.size设成了32768,为了使得整个参数达到预期效果,一样须要将kernel参数net.core.somaxconn设成一个大于等于32768的值。
  • 1
  • 2
  • 3
  • 4

2.关闭swap分区

避免使用swap分区,提供程序的执行效率。
除此以外,设置合理的预读取缓冲区的大小、文件系统选择与配置及I/O调度器选择等
  • 1
  • 2

JVM参数调优 
因为Hadoop中的每一个服务和任务均会运行在一个单独的JVM中,所以,JVM的一些重要参数也会影响Hadoop性能。管理员可经过调整JVM FLAGS和JVM垃圾回收机制提升Hadoop性能。

Hadoop参数调优

1.合理规划资源

设置合理的槽位数目
在Hadoop中,计算资源是用槽位表示的。slot分为两种:Map  Slot和Reduce Slot。每种slot表明必定量的资源,且同种slot是同质的,也就是说,同种slot表明的资源量是相同的。管理员须要根据实际须要为TaskTracker配置必定数目的Map Slot和Reduce Slot数目,从而限制每一个TaskTracker上并发执行的Map Task和Reduce Task的数目。
编写健康监测脚本
Hadoop容许管理员为每一个TaskTracker配置一个节点健康情况监测脚本。TaskTracker中包含一个专门的线程周期性执行该脚本,并将脚本执行结果经过心跳机制汇报给JobTracker。一旦JobTracker发现某个TaskTracker的当前情况为“不健康”,则会将其加入黑名单,今后再也不为它分配任务。
  • 1
  • 2
  • 3
  • 4

2. 调整心跳配置

调整心跳的间隔 因根据本身集群的规模适度的调整心跳间隔
启用带外心跳   为了减小任务分配延迟,Hadoop引入了带外心跳。带外心跳不一样于常规心跳,它是任务运行结束或者任务运行失败时触发的,可以在出现空闲资源时第一时间通知JobTracker,以便它可以迅速为空闲资源分配新的任务。

除此以外,还包括磁盘块配置、设置合理的RPC Handler和HTTP线程数目、慎用黑名单机制、启用批量任务调度、选择合适的压缩算法、启用预读取机制等。
注:当一个集群的规模较小时,若是必定数量的节点被频繁的加入系统黑名单中,则会大大下降集群的吞吐率和计算能力。
  • 1
  • 2
  • 3
  • 4
  • 5

四:YARN的内存和CPU配置

Hadoop YARN同时支持内存和CPU两种资源的调度,本文介绍如何配置YARN对内存和CPU的使用。

YARN做为一个资源调度器,应该考虑到集群里面每一台机子的计算资源,而后根据application申请的资源进行分配Container。Container是YARN里面资源分配的基本单位,具备必定的内存以及CPU资源。

在YARN集群中,平衡内存、CPU、磁盘的资源的很重要的,根据经验,每两个container使用一块磁盘以及一个CPU核的时候可使集群的资源获得一个比较好的利用。

一、内存配置

关于 内存 相关的配置能够参考hortonwork公司的文档 Determine HDP Memory Configuration Settings (https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.1.1/bk_installing_manually_book/content/rpm-chap1-11.html)来配置你的集群。

YARN以及MAPREDUCE全部可用的内存资源应该要除去系统运行须要的以及其余的hadoop的一些程序,总共保留的内存=系统内存+HBASE内存。

能够参考下面的表格肯定应该保留的内存: 
这里写图片描述

计算每台机子最多能够拥有多少个container,可使用下面的公式: 
containers = min (2*CORES, 1.8*DISKS, (Total available RAM) / MIN_CONTAINER_SIZE) 
说明:

CORES 为机器CPU核数
DISKS 为机器上挂载的磁盘个数
Total available RAM 为机器总内存 MIN_CONTAINER_SIZE 是指container最小的容量大小,这须要根据具体状况去设置,能够参考下面的表格
  • 1
  • 2
  • 3
  • 4

这里写图片描述

每一个container的平均使用内存大小计算方式为:

RAM-per-container = max(MIN_CONTAINER_SIZE, (Total Available RAM) / containers))

经过上面的计算,YARN以及MAPREDUCE能够这样配置: 
这里写图片描述

举个例子:对于128G内存、32核CPU的机器,挂载了7个磁盘,根据上面的说明,系统保留内存为24G,不适应HBase状况下,系统剩余可用内存为104G,计算containers值以下:

containers = min (2*32, 1.8* 7 , (128-24)/2) = min (64, 12.6 , 51) = 13

计算RAM-per-container值以下:

RAM-per-container = max (2, (124-24)/13) = max (2, 8) = 8

这样集群中下面的参数配置值以下: 
这里写图片描述

你也可使用脚本 yarn-utils.py (https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.1.1/bk_installing_manually_book/content/rpm-chap1-9.html)来计算上面的值:

python yarn-utils.py -c 32 -m 128 -d 7 -k False
  • 1

返回结果以下:

Using cores=32 memory=128GB disks=7 hbase=False Profile: cores=32 memory=106496MB reserved=24GB usableMem=104GB disks=7 Num Container=13 Container Ram=8192MB Used Ram=104GB Unused Ram=24GB yarn.scheduler.minimum-allocation-mb=8192 yarn.scheduler.maximum-allocation-mb=106496 yarn.nodemanager.resource.memory-mb=106496 mapreduce.map.memory.mb=8192 mapreduce.map.java.opts=-Xmx6553m mapreduce.reduce.memory.mb=8192 mapreduce.reduce.java.opts=-Xmx6553m yarn.app.mapreduce.am.resource.mb=8192 yarn.app.mapreduce.am.command-opts=-Xmx6553m mapreduce.task.io.sort.mb=3276
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

对应的xml配置为:

<property> <name>yarn.nodemanager.resource.memory-mb</name> <value>106496</value> </property> <property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>8192</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>106496</value> </property> <property> <name>yarn.app.mapreduce.am.resource.mb</name> <value>8192</value> </property> <property> <name>yarn.app.mapreduce.am.command-opts</name> <value>-Xmx6553m</value> </property>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

另外,还有一下几个参数:

yarn.nodemanager.vmem-pmem-ratio :任务每使用1MB物理内存,最多可以使用虚拟内存量,默认是2.1。 yarn.nodemanager.pmem-check-enabled :是否启动一个线程检查每一个任务正使用的物理内存量,若是任务超出分配值,则直接将其杀掉,默认是true。 yarn.nodemanager.vmem-pmem-ratio :是否启动一个线程检查每一个任务正使用的虚拟内存量,若是任务超出分配值,则直接将其杀掉,默认是true。
  • 1
  • 2
  • 3

第一个参数的意思是当一个map任务总共分配的物理内存为8G的时候,该任务的container最多内分配的堆内存为6.4G,能够分配的虚拟内存上限为8*2.1=16.8G。另外,照这样算下去,每一个节点上YARN能够启动的Map数为104/8=13个,彷佛偏少了,这主要是和咱们挂载的磁盘数太少了有关,人为的调整 RAM-per-container 的值为4G或者更小的一个值是否更合理呢?固然,这个要监控集群实际运行状况来决定了。 
CPU配置 
YARN中目前的CPU被划分红虚拟CPU(CPU virtual Core),这里的虚拟CPU是YARN本身引入的概念,初衷是,考虑到不一样节点的CPU性能可能不一样,每一个CPU具备的计算能力也是不同的,好比某个物理CPU的计算能力多是另一个物理CPU的2倍,这时候,你能够经过为第一个物理CPU多配置几个虚拟CPU弥补这种差别。用户提交做业时,能够指定每一个任务须要的虚拟CPU个数。

在YARN中,CPU相关配置参数以下:

yarn.nodemanager.resource.cpu-vcores :表示该节点上YARN可以使用的虚拟CPU个数,默认是8,注意,目前推荐将该值设值为与物理CPU核数数目相同。若是你的节点CPU核数不够8个,则须要调减少这个值,而YARN不会智能的探测节点的物理CPU总数。 yarn.scheduler.minimum-allocation-vcores :单个任务可申请的最小虚拟CPU个数,默认是1,若是一个任务申请的CPU个数少于该数,则该对应的值改成这个数。 yarn.scheduler.maximum-allocation-vcores :单个任务可申请的最多虚拟CPU个数,默认是32。
  • 1
  • 2
  • 3

对于一个CPU核数较多的集群来讲,上面的默认配置显然是不合适的,在个人测试集群中,4个节点每一个机器CPU核数为32,能够配置为:

<property> <name>yarn.nodemanager.resource.cpu-vcores</name> <value>32</value> </property> <property> <name>yarn.scheduler.maximum-allocation-vcores</name> <value>128</value> </property>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

总结 
根据上面的说明,个人测试集群中集群节点指标以下: 
每一个节点分配的物理内存、虚拟内存和CPU核数以下: 
实际生产环境中,可能不会像上面那样设置,好比不会把全部节点的CPU核数都分配给Spark,须要保留一个核留给系统使用;另外,内存上限也会作些设置。

小结

Hadoop 性能调优是一项工程浩大的工做,它不只涉及Hadoop自己的性能调优,还涉及更底层的硬件、操做系统和Java虚拟机等系统的调优。
整体来讲,提升做业运行效率须要Hadoop管理员和做业拥有者共同的努力,其中,管理员负责为用户提供一个高效的做业运行环境,而用户则根
相关文章
相关标签/搜索