引言
Hadoop生态圈的基石有两个,一个是HDFS文件系统,一个是MR编程框架。第一弹中提到应用MR编程框架实现大规模多机联合负载压测场景的方案,则突出了MR的能力,实际上HDFS作为这一切的基础,所起的作用是不容忽视的。
HDFS分布式文件系统与一般的文件系统,从本质构成上来说并没有太大的区别,普通磁盘上的文件系统,例如ext3有数据块(block),HDFS也有这个概念,ext3的分区表记录了文件与block、block与扇区的对应关系,同样HDFS的fsimage文件中也包含了这类信息。对于一个整体的分布式系统来说,HDFS包含两个重要角色,一个是中心节点Namenode,一个是数据节点Datanode。其中Namenode用来记录文件目录结构树,即元数据fsimag,和各种修改操作信息,即editlog。而Datanode则是数据真正存放的地方,Namenode获得RPC请求后会将这些请求根据特定算法分发到一些Datanode上。
由于存在单点结构,因此Namenode机器的性能必须远超Datanode机器,因为其负载了所有RPC访问请求,每个RPC请求引起的查询、IO、audit等动作都会消耗系统资源,Namenode的性能将会极大影响HDFS文件系统的整体性能。而相对来说Datanode的性能就不是那么重要了,当然这也区分具体的应用,例如对于HBase来说,由于Regionserver和Datanode同处于一台机器,彼此之间存在数据的交换,因此与Datanode的IO性能是有关联的,性能好坏成正比关系。
自从诞生HDFS开始,相关的性能压测工具就出现了,其中一些堪称经典之作更是检验HDFS性能的必用神器。例如Terasort,Slive,DFSIO,下面我就这几个工具的共同点和各自的特点做一个简单分析。
求同存异
Terasort
从文件系统角度出发的性能测试工具,大多不离吞吐率这个指标。转化到HDFS这边,则是rpc次数、opt次数、sync时长这样的指标信息,然而Terasort是个异类。这个工具不仅考验文件系统的性能,更是对MR自动排序能力的一种检测。Terasort位于hadoop的example包中,是SortBenchmark(http://sortbenchmark.org)排序比赛使用的标准工具,它使用了Hadoop默认的IdentityMapper和IdentityReducer,利用MR自有的sort机制来保证每个partition内数据是有序的。
显然我们使用Terasort,判断HDFS文件系统(其实还包含了MR)性能好坏的依据与SortBenchmark是一致的,即计算数据量和运行时长的比值,根据单位时间的排序数据量来判断不同HDFS版本之间的性能差异。
Terasort包含三个工具,分别是teragen:用来生成供排序的随机数据;terasort:用来将随机数据排序;teravalidate:校验terasort的排序结果是否正确。
通过控制teragen的map数和block size,我们得以检验多种测试场景下HDFS的性能状况。例如执行:
hadoop jar hadoop-current/hadoop-0.19.1-dc-examples.jar teragen -Dmapred.map.tasks=100 -Ddfs.block.size=134217728 10000000000 /terasort/output |
这个命令会在/terasort/output下生成100个10G大小的文件,文件的blocksize是128MB。这就类似于我们在测试单机磁盘IO的时候,分别要获取零碎文件吞吐率和整块大文件吞吐率数据一样。控制teragen生成的文件个数,文件大小,虽然总数据量一致,但是terasort的排序时间是有差异的。与普通磁盘不一样的地方在于,在集群资源不成为瓶颈的时候,文件越零碎,由于可以启动更多的map并行排序,相当于并发度提高了,terasort的总耗时就会变得更少。
SliveTest
SliveTest位于hadoop的test包中,代码结构清晰,其主要功能是通过大量map制造多种rpc请求,检测Namenode的性能。我们可以设定map数量,每个map发起的rpc请求次数,每一种rpc操作占总操作的百分比,以及读写数据量、block size等配置。下面列出slive可以调用的rpc操作种类:
ls |
列出路径下所有文件和目录 |
append |
追加写文件操作 |
create |
创建文件操作 |
delete |
删除文件操作 |
mkdir |
创建目录操作 |
rename |
重命名文件操作 |
read |
读取文件内容操作 |
默认情况下,每个map有1000次操作,7种操作均匀的随机出现。slivetest运行时相关参数如下表所示:
maps |
一共运行多少个mapper,默认值为10 |
ops |
每个map跑多少个操作,默认值为1000 |
duration |
每个map task的持续时间,默认值为MAX_INT,也就是无限制 |
exitOnError |
遇到第一个Error是否要立即退出,默认不退出 |
files |
最大生成文件数,默认为10 |
dirSize |
每个文件夹最多允许生成多少个文件,默认为32 |
baseDir |
SliveTest运行后默认存放的文件根目录,默认为“/test/slive” |
resFile |
结果文件名,默认为“part-0000” |
replication |
备份数,可设置最小,最大备份数,默认为3 |
blockSize |
设置文件block大小,默认为64M(64*1048576) |
readSize |
读入大小可设置为最小值,最大值形式,例如“-readSize 100,1000”,默认无限制(min=max=MAX_LONG=read entire file) |
writeSize |
写入大小,最小,最大形式,默认等于blockSize(min=max=blocksize) |
sleep |
在不同次操作之间随机的插入sleep,这个参数用于定义sleep的时间范围,设置同样是最小,最大,单位是毫秒,默认为0) |
appendSize |
追加写大小,最小,最大形式,默认等于blockSize(min=max=blocksize) |
seed |
随机数种子 |
cleanup |
执行完所有操作并报告之后,清理目录 |
queue |
指定队列名,默认为“default” |
packetSize |
指定写入的包大小 |
ls |
指定ls操作占总操作数的百分比 |
append |
指定append操作占总操作数的百分比 |
create |
指定create操作占总操作数的百分比 |
delete |
指定delete操作占总操作数的百分比 |
mkdir |
指定mkdir操作占总操作数的百分比 |
rename |
指定rename操作占总操作数的百分比 |
read |
指定read操作占总操作数的百分比 |
SliveTest可以给Namenode带来很大的压力,用来做极限情况下的压力测试非常合适。吴威大师(给大师拎包一直是我的荣幸)在SliveTest基础上更上一层,设计了多线程的SliveMapper,在多map多线程下压测Namenode,由于使用了上一篇文章中提到的应用MapReduce进行多机联合负载的思想,基本上可以将Namenode的极限性能完全压榨干净。大师制作的这个工具运行起来之后,Namenode就会处于一种假死状态,对其他rpc请求基本上失去响应,模拟出来的并发压力远远超过云梯当前线上的实际最大压力。作为每次云梯新版本上线前的必测工具,检测出的Hadoop性能瓶颈或发现的相关bug无数。(大师的思想有如茫茫大海中的明灯,指引我们前进的方向)
给大师拎包:
DFSIO
DFSIO是一个标准的HDFS的Benchmark工具,位于test包中。功能简单明了,测试的是读和写的性能指标。使用参数如下:
read |
读测试,报告保存在“io_read/part-00000”中。执行该测试之前,需要先做write测试,以便先行在io_data目录下生成供读取的文件。 |
write |
写测试,报告保存在“io_write/part-00000”中。 |
nfFiles |
文件个数,默认为1 |
fileSize |
文件大小,默认为1MB |
resFile |
结果文件名,默认为” TestDFSIO_results.log” |
bufferSize |
设置缓存大小,默认为1000000 |
clean |
清理数据 |
seq |
数据是否有序,默认无序 |
该工具作为一个辅助性质的性能测试工具,基本上可测可不测,因为优点已经被前述几个工具占光了,这个工具中规中矩,没什么好说的。
共性与注意点
大致介绍了那么几种性能测试工具,共性也可以抽象出来,HDFS的性能测试追求的是检测Namenode在正常环境、高负载环境下的性能表现。吞吐率是HDFS性能的一个重要指标,但是与传统单机文件系统的测试结果获取方法不同之处在于,我们通过HDFS代码中集成的ganglia相关模块来收集HDFS的性能指标,监控诸如total_iops、RpcProcessingTime_avg、Syncs_num_ops等指标。有关ganglia以及监控指标的相关内容,将在下一弹《指标监控工具浅谈》中进行分享。
此外,进行HDFS性能测试的时候,有一些外界环境条件也是需要注意的。首要之一是绝对不能启动SecondaryNamenode,这是因为SecondaryNamenode会同步editlog,或者做checkpoint,这都将占用Namenode的带宽和cpu资源,将干扰到性能测试获取到的结果数据。其次,为了降低环境因素的干扰,诸如RaidNode、Balancer等都不应该在性能测试中启动。HDFS文件系统中存在大量数据和没有数据测出来的性能测试结果也是有差异的,不能用来做性能对比,这是因为在文件目录结构树中的查找也会消耗一定的系统资源。
理想的情况是准备一套干净的只有Namenode和Datanode两种角色的HDFS文件系统,然后将上述测试工具放在这个环境中运行获取测试结果,用这个结果来与以前的版本做对比来获得对新版本性能优劣的评价。
压力测试
前述工具更关注性能方面的测试,实际上,性能和压力总是像一对亲兄弟,经常出现在同样的测试环境中。对于压力测试,我们通过制造大量的block、文件以及数据量来达到目的。测试团队自己设计制作了线上压力仿真工具,同样采用上一篇提到的技术,可以在短短的一天内将block数、文件数造到和线上一致。使得Namenode节点庞大的内存资源被占用去80%以上(本文由于公开发表,相关数据不便公开)。然后再在这样的环境下使用性能测试工具检测HDFS的性能。云梯测试环境对于线上压力的仿真能力非常有限,经过测算仿真的上限基本上是1:10的关系,即100台机器集群可以仿真1000台的实际环境。这里瓶颈不在Namenode,而是在Datanode上,由于机器少,block分散在Datanode上就会占用更多的内存、cpu资源,datanode的吞吐率也会下降,这样一来性能测试受datanode性能的影响就无法发挥最大作用,测试结果失去参考价值。
总结
HDFS下常用的性能压测工具不仅有本文提及的几种,还有如“nnbench”,“randomwriter”,“randomtextwriter”等可以使用。本文所提及的则是最具代表性的几种常用测试工具。海量数据的性能测试一直是这个领域的焦点,从熟悉这些工具入手,我们可以更快的切入到这个领域中。性能测试是一个说不完的话题,相关讨论也是层出不穷,本文至此收尾,谨以此文作为触摸Hadoop两年来的一个总结。