Hadoop 性能调优 重要参数设置技巧

2019-03-28 13:16|来源: 网络

这里主要针对Mapreduce的性能调优。

这一两个月在做mapreduce的性能调优,有些心得,还是要记下来的,以郷后人~

这里主要涉及的参数包括:

  1. HDFS:
  2. dfs.block.size
  3. Mapredure:
  4. io.sort.mb
  5. io.sort.spill.percent
  6. mapred.local.dir
  7. mapred.map.tasks & mapred.tasktracker.map.tasks.maximum
  8. mapred.reduce.tasks & mapred.tasktracker.reduce.tasks.maximum
  9. mapred.reduce.max.attempts
  10. mapred.reduce.parallel.copies
  11. mapreduce.reduce.shuffle.maxfetchfailures
  12. mapred.child.java.opts
  13. mapred.reduce.tasks.speculative.execution
  14. mapred.compress.map.output & mapred.map.output.compression.codec
  15. mapred.reduce.slowstart.completed.maps

这里一共列出了十六个参数,这十六个参数基本上能满足一般情况下,不针对特定场景应用的性能调优了,下面我将以Terasort为例,详述这些参数的作用已经如何配比调优。

Hadoop的HDFS作为mapreduce的基础分布式文件系统,对mapred的运行效果也有直接的影响。首先影响到我们的性能的参数就是block.size,在网络环境很好的集群中,建议将这个参数提升,大小可以到128或256或更大(默认64M)。

但是HDFS的影响也仅限于此,而且其配置项多数都是目录配置以及容错,还有备份数等等,这些对于我们性能调优意义不大。可以举一个例子,那就是备份数。这个参数主要是用于设置block在集群中的备份数,这些备份将按照某种规则分配在集群的各个机器上,默认是3备份。但是由于mapred的map需要输入数据,一般默认情况是一个map一个block,那么当你在集群起job,一个job拉起来N多的map在一个机器执行时,如果这个map的输入数据是本地的,那么显然map的执行将会更快,因为不需要等待网络传输。拿四个节点为例,如果你设置三备份,那么你不管存什么数据,任何一台机器上可以存数的你的数据的量都是3/4,。但是如果你设置为四备份,那么任意一个节点上都能完整的找到你的数据,那么不管你怎么起job,你的map都将是本地化的。但是带来的坏处就是磁盘开销过大,一般大型的集群也承受不了5备份以上的数据量,所以,基本无意义。

下面来谈谈重头戏,那就是mapred中的这些NB的参数。前置知识我相信大家都已经了解了(如果你还不了解mapred的运行机制,看这个也无意义...),首先数据要进行map,然后merge,然后reduce进程进行copy,最后进行reduce,其中的merge和copy总称可以为shuffle。在你起一个job前,hadoop需要知道你要启动多少个map,多少个renduce进程,如果你进行默认参数启动,那么默认只有一个map线程。(reduce也许也是一个..)这个速度是很慢的。设置map启动个数的参数是mapred.map.tasks,reduce则是mapred.reduce.tasks。这两个参数可以说是对整个集群的性能起主导型作用的参数,调试也基本上围绕这两个参数。那大家要问就两个参数有什么好来回修改的呢?其实,这两个参数的设置配比也直接影响到其他的参数的设置。首当其冲的就是mapred.tasktracker.map.tasks.maximum 以及 mapred.tasktracker.reduce.tasks.maximum。因为这两个参数设置了一台服务器上最多能同时运行的map和reduce数。现在我们来假设一个集群有一个namenode以及8个datanode,这是一个很客观的集群。我们假设上面的数据都是三备份,那么本地数据率为3/8。假设你设置的map.tasks=128,reuce.tasks=64,那么你的对应的两个maximum就应该分别为16以及8或是更高。因为这样才能保证你的所有map和reduce的任务都是分别同时启动的,如果你的设置reduce的maximum为7,那么你将得到非常糟糕的结果,因为这样8台机器同时可以运行的reduce数量为56了,比你设置的64差8个进程,这八个进程将会处于pending状态,直到某些正在运行的reduce完成它才能补上运行,势必大幅度的增加了运行时间。当然,这也不是越大越好,因为map有很长的一段时间是和reduce进程共存的,共存的时间取决于你设置的mapred.reduce.slowstart.completed.maps,如果你设置为0.6.那么reduce将在map完成60%后进入运行态。所以说,如果你设置的map和reduce参数都很大,势必造成map和reduce争抢资源,造成有些进程饥饿,超时出错,最大的可能就是socket.timeout的出错,网络过于繁忙。所以说,这些需要根据集群的性能,适当调试添加和减少,以达到最好的效果。那么,map和reduce之间是怎样的配比比较好呢?apache官网给了我们一些建议,比如设置reduce与map,他们之间有一个具体的公式。但是实际情况总是不能用公式来套用的(否则就不需要系统工程师了...)。一般情况下,当你设置好map和reduce进程数后,你可以通过hadoop的mapred的页面入口(http://namenode:50030/jobdetai.jps)查看map和reduce进度,如果你发现reduce在33%时,map正好提早一点点到100%,那么这将是最佳的配比,因为reduce是在33%的时候完成了copy阶段,也就是说,map需要再reduce到达33%之前完成所有的map任务,准备好数据。千万不能让reduce在等待,但是可以让map先完成。

OK!这个重点的搞完之后我们在看看两个息息相关的参数,io.sort.mb和mapred.child.java.opts。因为每一个map或是reduce进程都是一个task,都会对应启动一个JVM,所以其实java.opts也与你启动的map和reduce数以及别的一些jvm敏感的参数有关。既然task运行在JVM里面,那么,我这里所要提到的sort.mb 也是分配在JVM中的,这个值是用来设置到底我一个map sort的可用buffer大小是多少,如果map在内存中sort的结果达到一个特定的值,就会被spill进入硬盘。具体这个值是等于mb*io.sort.spill.percent.。按照通常的设置方式,为了让jvm发挥最佳性能,一般设置JVM的最大可用内存量为mb设置的内存量的两倍。那么mb的内存量又根据什么设置呢?它主要是与你的一个map的结果数据量有关。如果一个map的结果数据量为600M,那么如果你设置的mb*io.sort.spill.percent.=200M,那么将进行3次spill进入硬盘,然后map完成后再将数据从硬盘上取出进行copy。所以,这个mb设置如果是600M的话,那么就不需要进行这次硬盘访问了,节省了很多时间。但是最大的问题是内存耗费很大。如果mb是600M,那么jvm.opts将需要设置为1G以上,那么,按照上例,你同时启动16个map和8个reduce 的话,那么你的内存至少应该有24G。所以,这里的设置也要慎重,因为毕竟你的服务器还要跑很多其他的服务。

下面就讲一下别的一些有影响的参数,按照一般的设置方法就可以。首先是针对磁盘和磁盘IO的,mapred.local.dir,这个参数最好设置的跟你的磁盘数相同,你的磁盘应该每一个磁盘都单独设置为RAID0,然后将所有磁盘配置成多路径在这个配置项下,那么HDFS在决定数据存储时会顺序循环存储,保证所有磁盘数据量的一致性,也提升了整体磁盘的IO速度。那么针对于网络,主要是有reduce和map同时运行时需要慎重考虑。mapred.reduce.parallel.copies与mapreduce.reduce.shuffle.maxfetchfailures这些参数都是对网络有一些影响的。第一个是reduce可以进行的最大并行拷贝线程数,这些线程会同时从不同的datanode上取map结果,而第二个出错重试次数过多对于很多我们的应用都是降低性能的一个问题。因为一般一个job重试了1次没有成功那基本以后无论怎么重试都是不会成功的,重试了不成功不要紧,关键是这个重试还大量的消耗系统的资源,让其他的线程可能也因为starvation 而进入重试状态,恶性循环了。如果说你的网络确实很成瓶颈,千兆网都达不到,那么建议打开mapred.compress.map.output压缩选项,并配置 mapred.map.output.compression.codec压缩编码格式,一般都会使用snappy,因为这种格式对于压缩和解压缩都相对较快。还有就是如果你的集群是异构的,有些机器性能好,有些差,那么建议打开mapred.reduce.tasks.speculative.execution推测性执行,有利于优化进程分配,提升集群性能。

如有不详或不对的地方,还请指正。

相关问答

更多
  • 问题1,关于JVM GC设置的这一大串参数,是跟在 java 启动命令行中。作用是设置 java 虚拟机启动参数。 比如: java -jar basesvr.jar -Xmx5g -Xms5g -XX:+UseG1GC -XX:+PrintFlagsFinal -XX:+PrintReferenceGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintAdaptiveSizePolicy -XX:+UnlockDiagnos ...
  • 优化WebLogic 服务器性能参数 WebLogic 配置文件(config.xml)包含了大量很直观的与性能有关的参数,能通过配置环境与应用程序得到很好的优化。基于系统的需要调整这些参数不仅能改善单个点的性能,而且能提高整个应用程序性能的可衡量性。 试着采用下列WebLogic配置方法,或许能使你的系统达到最佳状态: 一 修改运行队列线程数的值。在WebLogic 中队列元素的线程数等于同时占用运行队列的应用程序的数目。当任务加入一个WebLogic 实例,它就被放到执行队列中,然后分配给任务一个线程来 ...
  • 坏消息:有GUI工具帮助这一点,但它的技能和广泛的工作。 所以他们不覆盖一切,它可能需要使用命令行的东西/ sql语句等来帮助。 我只是真的使用了命令行工具。 我会给出一些我所知道/使用的东西的概述: 首先,你需要一个很好的数据库设计。 如果设计不好,你只能到现在为止。 这包括规范化,以及对字段使用适当的类型。 我会把这一点留在这里,因为我觉得它有点放在一边,而不是你以后。 确保MySQL查询缓存设置和工作,并给它一个更多的RAM,如果可以,并确保您的重要查询没有做任何阻止mysql缓存他们。 例如,在查询 ...
  • 使用bash而不是sh来调用脚本。 这解决了我的问题。 Use bash and not sh to invoke the scripts. That solved my problem.
  • 只要工作者在同一节点上,我们就具有Locality的优势。 您也可以与hadoop一起启动服务。 As long as the worker is on the same node, we have the advantage of Locality. You can launch your service alongside hadoop as well.
  • 根据异常的消息,您希望在已关闭的连接上应用db操作(无论是创建,选择,更新还是删除)。 你能过一些代码吗? 顺便说一句:我正在运行bonecp 0.8.0,并且我没有遇到使用这个(开发)配置的这些异常: db { default.driver=org.postgresql.Driver default.url="jdbc:postgresql://.../database" default.user=some-user default.password="some-pass" defau ...
  • 不,您无法动态更改每个节点的每个作业的MapReduce参数。 配置节点集 相反,您可以做的是在配置文件(通常位于/etc/hadoop/conf )中静态更改每个节点的配置参数,以便您可以使用不同的h / w配置充分利用群集。 示例:假设您有20个具有不同硬件配置的工作节点,例如: 10配置128GB RAM,24个核心 10配置64GB RAM,12个核心 在这种情况下,您可能希望配置每个相同的服务器以充分利用硬件,例如,您希望在具有更多RAM和内核的工作节点上运行更多子任务(映射器和缩减器),例如: ...
  • 您应该描述您想要的行为。 最大线程约束为100的工作管理器不会将您的应用程序限制为100个用户,但会将其限制为同时为100个并发请求提供服务。 http://blogs.oracle.com/jamesbayer/entry/weblogic_server_work_manager_demo 如果要将其限制为100个用户,请考虑在使用会话时设置最大内存中会话。 您可以在weblogic.xml部署描述符中或在部署的configuration-> general部分的wls控制台中进行设置。 http://d ...
  • 这取决于很多因素,包括配置,机器,内存配置,JVM设置等。还需要减去JVM启动时间。 它对我来说运行速度要快得多。 也就是说,小数据集的速度当然比专门的C程序要慢 - 请考虑它在“幕后”做了什么。 尝试使用数千个数据分布在几千个文件中,并查看会发生什么。 This depends on a large number of factors, including your configuration, your machine, memory config, JVM settings, etc. You als ...
  • 这可能发生在作业仅检测到本地文件系统的情况下,它使用LocalFileSystem API与本地文件系统中的文件进行交互。 请参考以下链接, 使用MiniDFSCluster单元测试hadoop hdfs着作 这是我们在开发环境中开发的mapreduce / hdfs代码的单元测试选项之一。虽然在hadoop clsuter中部署相同的代码,但输入文件将在HDFS位置。 This probably happens in the scenario where the job only detects the ...