来自于某本大牛英文专著。翻译稿。 讲解在Hadoop中的性能调优。介绍MapReduce性能的影响因子,如何诊断Map的性能瓶颈。
6.2 诊断性能瓶颈
有的时候作业的执行时间会长得惊人。想靠猜也是很难猜对问题在哪。这一章中将介绍如何界定问题,找到根源。涉及的工具中有的是Hadoop自带的,有的是本书提供的。
系统监控和Hadoop任务 在Hadoop的0.20.x版本中,并没有提供MapReduce任务的CPU和内存的性能指标的抽取方法。不过在0.22版本中,CPU和内存性能指标将会被写道作业的历史信息文件中。并且可以通过Hadoop的用户界面来查看这些。 |
6.2.1 理解MapReduce作业性能的影响因子
从大的方面来讲,对作业性能有负面效应的影响因子可以分为如下几个大类:
- Hadoop配置。默认设置在大部分服务器集群平台上的性能是非常低下的。但如果自定义的配置没配好,情况也不会有多好。配置所导致的常见性能问题有内存频繁交换,CPU过载等等。
- Map任务。特别大的文件和特别小的文件都会影响Map任务的性能。性能低下的代码也会有影响。
- Reduce任务。数据倾斜(data skew),reduce的数量,未经优化的代码都会影响reduce的性能。
- 硬件。集群会被部分糟糕的节点和网络原因影响。特别是那种不够大的集群。
这一章将会介绍作业性能低下的常见场景及解决方案。这些场景和方案将会分别在上述4大类别中介绍。
图6.3种有一个决策树,用以根据性能问题的特别界定原因和解决方案。
6.2.2 Map的性能问题
图6.4是map任务中的各个基本单元,并标识出了可能影响性能的区域。
技术28 调查输入数据中的特别大的部分
如果处理的数据突然增长到特别大,超出预期,那作业就会变得很慢。例如,有一天网站的访问量突然飙升,产生了异乎寻常的大的日志文件。就会导致MapReduce作业变慢。
问题
如果在map或reduce有特别大的输入数据,能够被快速地发现或诊断出来。
方案
使用JobTracker UI将运行较慢的作业的当前输入输出数据的大小和历史信息相比较。
讨论
在JobTracker UI中选择运行很慢的作业。在作业概述信息中可以看到作业的性能统计信息。如图6.5所示。
把这些信息和作业的历史信息相比较,就可以找到运行缓慢的原因了。
小结
要理解将会被作业处理的数据的特性。有的数据会有产生特别大的数据的时候,有的没有。
技术29 诊断map端的数据倾斜(data skew)
数据倾斜是不可避免的。在map端,一般有两个原因造成数据倾斜:
- 大量的不可分块的超大文件
- 大量的小文件
问题
需要诊断是不是由于数据倾斜导致了作业运行缓慢
方案
使用JobTracker UI来比较同一个作业所有map任务的输入数据的大小。
讨论
由于数据倾斜会导致部分任务的运行时间要比其它的要长。只要把这些有拖延症的迟迟不完成的任务和其他已完成的任务的输入数据的大小比较一下,就很容易可以把数据倾斜的问题找出来。
图6.6介绍了使用JobTracker UI来诊断数据倾斜的步骤。
小结
如果已经确定了数据倾斜,下一步就是考虑如何减轻数据倾斜对作业的影响。技术50和51介绍如何诊断数据倾斜的成因。(这两个技术在6.4.3。)
技术30 诊断map任务的低吞吐量问题
这个技术中将介绍如何诊断map任务是否存在低吞吐量问题,以及问题的成因。
问题
需要诊断是否是任务的低吞吐量导致了作业运行缓慢。
方案
用JobTracker UI或作业的历史信息源数据中的性能指标来计算map任务的吞吐量。
讨论
有以下方法可以得到某个任务的map任务的吞吐量:
- 使用JobTracker来得到任务的执行时间。再如图6.7所示计算map任务的吞吐量。
- 用TaskThroughput类(源: http://goo.gl/QQvvQ)基于作业历史信息文件得到所有map任务的吞吐量统计信息。如图6.8所示。
小结
得到计算结果后,需要根据实际情况来判断吞吐量是高还是低。如果数据来自于本地节点,那么可以以本地磁盘的读取吞吐量为对照。如果数据来自于HDFS以外,就需要以数据的读取速率,hadoop节点和数据源之间的读取延迟等作为对照。
有以下几点可以导致map任务的吞吐量变低:
- 源文件的大小远小于HDFS的块的大小。这意味着任务的开启和停止要耗费更多的时间,就没有足够的时间来读取并处理输入数据。
- 源文件无法分块。这导致需要通过网络IO从其他节点读取文件块。
- 一个节点的本地磁盘或磁盘控制器运行在降级模式中,读取写入性能都很差。这会影响某个节点,而不是全部节点。
- 源文件不来自于HDFS。则可能是Hadoop节点和数据源之间的延迟导致了性能低下。
- Map任务从其他数据节点读取数据。可以从JobTracker的map任务细节信息和任务运行尝试中找到输入块的位置。如果输入块的位置不是任务执行的节点,那就不是本地数据了。
上述各点将分别有对应技术来诊断低吞吐量的具体成因。
技术31 小文件
在作业中,数以千计的小文件将会导致数以千计的JAVA任务来处理他们。这显然是效率低下的。
问题
需要诊断是否是小文件导致了作业运行缓慢。
方案
使用JobTracker UI或作业历史源数据来检查输入块的大小。
讨论
通过目测JobTracker中的作业的map任务列表中的输入文件,就可以得到map任务的输入数据的大小。图6.9介绍了一个有小文件作为输入源的归属同一个作业的map任务列表。
此外,还可以从作业统计信息摘要工具(https://github.com/alexholmes/hadoop-book/blob/master/src/main/java/com/manning/hip/ch6/MetricSummary.java)得到map输入大小的字节数的最小值,最大值,平均值和中位数。如图6.10所示。
小结
如果作业的输入文件远远小于HDFS的块的大小,集群就很有可能没有足够的时间来处理数据。第5张中介绍了很多提高处理小文件的效率的方法。
技术32 不可分块的文件
如果作业的输入文件无法分块(例如:某些压缩格式,二进制文件等等),那么数据就没办法得到序列化优化处理了,并且无法在HDFS本地处理。这个技术将介绍如何诊断作业的不可分快的文件的问题。
问题
需要诊断是不是不可分块的文件导致了作业运行缓慢。
方案
使用JobTracker UI或作业历史源数据来诊断输入块是否过大。
讨论
通过目测JobTracker中作业的map任务列表的输入文件,可以找到其中是否有不可分块的超大文件。如图6.11所示。
此外,还可以用作业统计信息摘要工具(https://github.com/alexholmes/hadoop-book/blob/master/src/main/java/com/manning/hip/ch6/MetricSummary.java)得到map输入大小的字节数的最小值,最大值,平均值和中位数。如图6.12所示。
用JobTracker来查看map任务的列表,并计算每个map人物的输入字节数的平均值。
小结
如果作业输入文件远远大于HDFS的块的大小,那么集群将要分配大量的槽(slot)来处理这些大文件。由于这些输入文件无法分块,还会有大量的槽(slot)无法利用。
如果发生了这种情况,那么首先要想的就是,这是不是和预期的一样。因为不基于块的二进制文件就是要这样处理。但如果是压缩文件,如LZOP和BZIP2之外的压缩格式,就可以考虑一下是不是要更换压缩格式。第5张的表5.2列出了Hadoop中支持的所有压缩格式以及它们对分块的支持。
尽管LZOP格式可以分块,但仍然有两种情况无法分块:
- LZOP文件没有索引,无法分块。如果是这种情况,可以参考第5张来创建索引文件。
- 不用LZOP的InputFormat来处理LZOP文件。不是LZOP的InputFormat不知道如何对LZOP文件进行分块。如果要对LZOP进行分块,应该用名字开头为lzo的InputFormat,如LzoTextInputFormat。第5章中有详细介绍。
这介绍了map任务性能影响因素的所有情况。下一步,将介绍reduce任务的性能的影响因素。