对Hadoop task进行profiling的几种方法整理

2019-03-28 14:10|来源: 网络

Hadoop中,当一个job的调试完成,执行成功后,job的开发者接下来该思考的问题通常就是:如何将job跑的更快,更加高效,更节省资源呢?这个话题其实是一个老生常谈的话题了,很多有经验的工程师,开发人员和机构都分享过类似的经验。通常来说,应用程序千变万化,程序逻辑也不尽相同,程序的执行瓶颈通常也不尽相同,有的job是IO密集型的作业,那么优化其算法效率意义就不大,而有的job是CPU密集型的,那么对其中间结果压缩,或者调整类似io.sort.mb,io.sort.factor等参数也就没有什么太大作用,优化程序算法肯定会有更大收益。

    所以在大多数情况下,写job,调试job,测试,上线运行,这套开发mapreduce应用程序的流程通常很多开发团队都走的很顺。但这并不是最难的,事情到这里也还远远不算完,程序哪里不高效,哪里消耗过多资源,哪里是瓶颈,如何优化,这一系列的问题,根据在下的经验,是开发团队考虑的相对不多的地方。

    通常应用程序的开发者发现自己的hadoop job跑的不够高效,不够快的时候,第一时间想到的,是给hadoop平台的开发团队写邮件,说你hadoop平台又怎么怎么样,害的我的job跑的不够高效,然后在邮件的最后还附加上一句:“请hadoop平台开发团队多多考虑用户的建议和用户体验,优化hadoop,满足我这个什么什么job的需求,不然我就 @#¥%#¥%#”。而其实大部分情况下,只要稍微关注一下自己的程序,稍微进行一些优化,作业的执行效率就会高很多。说到这里内心又开始有些激动,还是言归正传吧……

     刚才说到作业效率和瓶颈的问题,怎么发现作业的瓶颈呢?用户怎么知道他的作业的在哪个阶段最耗时,哪个地方最耗内存呢?其实hadoop提供了用户tunning自己job的方法,其中profiling tasks就是其中一种。

     和debug task一样,profiling一个运行在分布式hadoop环境下的mapredeuce job是比较困难的。但在hadoop中,是可以让用户针对某些tasks进行profiling采集的,当这些task执行完后,将这些profiling日志保存的文件发送到作业的提交client机器上,然后用户就可以用自己熟悉的工具来分析这些profiling日志,进行tasks执行瓶颈的分析。

 

使用方法:

  在JobConf中,有几个配置选项是可以用来控制task profiling行为的。比如对一个job,想要开启对其tasks的profiling功能,并设置profiling相应的HPROF参数,可以按如下方式:

 

conf.setProfileEnabled(true);
conf.setProfileParams("-agentlib:hprof=cpu=samples,heap=sites,depth=6," +
"force=n,thread=y,verbose=n,file=%s");
conf.setProfileTaskRange(true, "0-2");

第一行表示打开profiling task的功能,该功能默认情况下是关闭的。调用该接口相当于设置配置选项 mapred.task.profile=true,可以利用这种方式在hadoop job提交命令行上动态指定。

 

第二行是通过conf接口来设置对tasks进行HPROF 的profiling的采集参数,采用profiling enable的方式运行的tasks,会采用每个task一个独立的JVM的运行方式运行(即使enable了job的jvm reuse功能)。HPROF相关的采集参数设置,可以见其他资料。该选项也可以通过设置 mapred.task.profile.params 选项来指定。

 

第三行表示对job的哪些tasks需要进行profiling采集,第一true参数表示采集的是map tasks的性能数据,false的话表示采集reduce的性能数据,第二个参数表示只采集编号为0,1,2的tasks的数据,(默认为0-2)。如果想要采集除2,3,5编号的tasks,可以设置该参数为: 0-1,4,6-

 

Example

   还是拿wordcount来举例,提交job命令如下:

 

bin/hadoop jar hadoop-examples-0.20.2-luoli.jar wordcount /
  -D mapred.reduce.tasks=10 /
  -D keep.failed.task.files=fales /
  -D mapred.task.profile=true /
  -D mapred.task.profile.params="-agentlib:hprof=cpu=samples,heap=sites,depth=6,force=n,thread=y,verbose=n,file=%s" /
  $input /
  $output

 

这样,当job运行时,就会对前三个task进行profiling的采集,采集信息包括cpu的采样信息,内存分配的信息数据,stack trace 6层的堆栈信息。这里需要注意的是,由于前三个tasks被进行了HPROF的性能采样,所以这几个tasks的执行效率会受到一定的影响,profiling的信息越详细,性能影响就越大。如下图,前三个map就明显比其他的map运行的要慢很多。

不过这种运行方式通常都不是线上运行方式,而是用来进行优化调试,所以关系不大。

 

而当job运行完成后,这三个tasks对应的profiling日志也会会传到提交机器上,供用户分析判断。如下图:

 

与此同时,tasks在tasktracker上也将这些profiling日志信息记录到了一个profile.out的日志文件中,该文件通常位于tasktracker机器上的上${HADOOP_HOME}/logs/userlogs/${attempt_id}下,和该task的stderr,stdout,syslog保存在同一个目录下,如下图:

 

该文件中的内容,还可以通过taskdetails.jsp的页面查看到。如下图:

 

 

有了这些信息,相信对于任何一位hadoop应用程序的开发者来说,就拥有了足够的定位job瓶颈的信息了。MR的应用程序开发同学,请优化您的job吧~~

相关问答

更多
  • 现在hadoop1.0都出了 简单说一下吧 你的java jdk的环境变量没有设置吧? 最好按以下步骤再做一遍: 1 用root用户安装jdk1.6以上 2 用root用户 创建hadoop用户 3 在hadoop用户下安装hadoop(你上面说的1到4) 4 修改/home/hadoop/.bash_profile将JDK和hadoop的环境变量设置好 5 安装ssh(伪集群也需要ssh)
  • 做了一个全新安装的hadoop并用同一个罐子运行工作,问题就消失了。 似乎是一个错误,而不是编程错误。 Did a fresh installation of hadoop and ran the job with the same jar, the problem disappeared. Seems to be a bug rather than programming errors.
  • 试试这个 您也可以使用JAQL 。 它是在Map Reduce中处理JSON的最简单方法。 不好的是你必须学习JAQL(除非你已经知道)! Try this You can also use JAQL. Its the easiest way to deal with JSON in Map Reduce. Bad thing is that you will have to learn JAQL (unless you know it already) !!
  • 您需要为openCV安装所需的包。 这篇文章介绍如何安装openCV: http : //www.samontab.com/web/2012/06/installing-opencv-2-4-1-ubuntu-12-04-lts/ 您需要的是以下命令: sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff4-dev libjasper-dev libopenexr-dev cmake python-dev python- ...
  • Hadoop有asm 3.2而我使用的是ASM 5.在ASM5中,ClassVisitor是一个超类,而在3.2中它是一个接口。 出于某种原因,错误是Throwable(信任Shevek),catch块只捕获异常。 任何hadoop日志都没有捕获throwable错误。 因此,调试非常困难。 使用jar jar链接修复asm版本问题,现在一切正常。 如果你正在使用Hadoop并且某些东西不起作用并且没有日志显示任何错误,那么请尝试抓住Throwable。 阿伦 Hadoop had asm 3.2 and ...
  • TaggedWritable类没有空构造函数,因此在应该读取序列化数据的reduce阶段,app会因为无法通过反射创建TaggedWritable键入键而TaggedWritable 。 您应该添加一个空构造函数。 您的地图阶段已成功完成,因为在地图阶段,您的映射器会TaggedWritable创建TaggedWritable类型的键。 This code solves the problem and gives the expected result. It is from here, public st ...
  • 假设zipIn是java.util.zip.ZipInputStream ,你不应该迭代地调用getNextEntry而不是读取字节吗? I resolved this issue after doing some changes in my code. In the first part of code, I was trying to unzip all the zip files whereas I should have access the spilts. Hadoop basic, which ...
  • KMS基本上是HDFS本机数据加密实用程序的一部分,用于存储加密密钥。您现在可以加密HDFS中的选定文件或目录,而无需更改任何应用程序代码。 HDFS管理员设置加密,然后HDFS负责实际加密或解密,而最终用户无需手动加密或解密文件。 以下术语描述了透明数据加密(TDE)的关键领域: 加密区域 - HDFS管理员创建加密区域,然后将其链接到空的HDFS目录和加密密钥。 放入目录中的所有文件都由HDFS自动加密。 密钥管理服务器(KMS) - KMS负责存储加密密钥。 KMS为存储在KMS中的密钥提供REST ...
  • 您可以使用Sqoop将数据从RDBMS导入Hadoop。 Hadoop会处理非结构化数据,因为您将约束(创建结构化数据)推到了最后。 这也允许创建什么样的结构,这将定义您可以提取的信息类型。 永远不会说您无法处理结构化数据,但获得的里程数很低。 RDBMS可以高效地处理结构化数据。 You can use Sqoop to import data from RDBMS to Hadoop. Hadoop shines at processing unstructured data because you a ...
  • 你是部分正确的。 为了避免Jobtracker做出调度和监控的负担,YARN被引入了画面。 因此,对于YARN,您没有任何作业跟踪器或任务跟踪器。 Job跟踪器完成的工作现在由资源管理器完成,资源管理器有两个主要组件Scheduler(为应用程序分配资源)和ApplicationsManager(接受作业提交并在发生任何故障时重新启动ApplicationMaster)。 现在每个应用程序都有一个ApplicationMaster,它从调度程序协调容器(将运行作业的位置)以运行应用程序。 Nodemanag ...