1. 背景

在部署Hadoop集群时,作为集群运维人员,往往需要了解集群性能。即集群能够处理数据的上限,集群的瓶颈等信息。特别是在上线一批尚未使用过的机型、磁盘时,更需要了解这些硬件上的变更是否会对集群整体性能有影响。本文介绍当DataNode挂载juicefs情况下,集群的性能表现;并且和只挂载Disk磁盘时的性能进行对比。

2. HDFS压测工具介绍

  1. Terasort:基于MapReduce的数据排序压测工具,当需要测试集群的计算能力时可以使用该工具进行压测。
  2. SliveTest:HDFS RPC压测工具。
  3. DFSIO:IO吞吐量压测工具。

2.1 Terasort

Terasort包含三个工具,分别是:

  1. teragen:用来生成供排序的随机数据;
  2. terasort:用来将随机数据排序;
  3. teravalidate:校验terasort的排序。

执行命令如下:


# 在/terasort/output下生成100个10G大小的文件,文件的blocksize是128MB
# /tmp/test/terasort/output 事先要删除
hadoop jar hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples.jar teragen -Dmapred.map.tasks=100 -Ddfs.block.size=134217728 10000000000 /tmp/test/terasort/output

# 对生成的文件进行排序
hadoop jar hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples.jar terasort -Dmapred.reduce.tasks=100 /tmp/test/terasort/output /tmp/test/terasort/result

# 对排序结果进行验证
hadoop jar hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples.jar teravalidate  /tmp/test/terasort/result /tmp/test/terasort/validate

Terasort使用场景:

  1. 不同版本Hadoop上运行TeraSort,使用相同的配置参数,来进行正确性和性能对比测试。
  2. 在相同版本Hadoop上运行TeraSort,使用不同的配置参数,进行性能对比测试,发现问题。例如设置不同的map数和block size检测HDFS性能状况。

2.2 SliveTest

SliveTest主要功能是通过大量map制造多种rpc请求,检测Namenode的性能, 位于test包(hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar)中。SliveTest 可模拟以下多种RPC 操作(ls, create, append,delete,mkdir,rename,read),可能会造成NN 大量RPC, 生产环境不要运行。

执行命令如下:

# 并发量跟map数量有关
hadoop jar hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar SliveTest -maps 90 -ops 10000 -files 100 -resFile /tmp/slivetest.txt

配置建议:可以设定map数量,每个map发起的rpc请求次数,每一种rpc操作占总操作的百分比,以及读写数据量、block size等配置。

2.3 DFSIO

DFSIO是一个标准的HDFS的Benchmark工具,位于test包(hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar)中, 测试的是读和写的性能指标,执行完后会打印IO吞吐率。

由于DFSIO可以直接测试HDFS的读写性能,往往替代Terasort工具。

执行命令如下:

# 写入性能测试(写10个文件,每个文件1GB,会创建一个有10个map的mr任务,每个map分配1C4GB资源)
hadoop jar hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar TestDFSIO -write -nrFiles 10 -size 1GB -resFile /tmp/writeres.txt

# 读文件性能测试
hadoop jar hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar TestDFSIO -read -nrFiles 10 -size 1GB -resFile /tmp/readres.txt

参数配置解释:

read : 读测试。执行该测试之前,需要先做write测试,以便先行在io_data目录下生成供读取的文件。
write :写测试,报告保存在“io_write/part-00000”中。
nfFiles :文件个数,默认为1
fileSize: 文件大小,默认为1MB
resFile:  结果文件名,默认为"TestDFSIO_results.log"
bufferSize: 设置缓存大小,默认为1000000
clean:清理数据
seq :数据是否有序,默认无序

其输出如下为例:

Untitled.png 输出解读:

  • Total MBytes processed:总共需要写入的数据量,也就是总文件数*单个文件的大小,单位MB。
  • Throughput mb/sec:总共需要写入的数据量/每个map任务实际写入数据的执行时间之和,这个值可以看做是hdfs的写入性能。
  • Average IO rate mb/sec:(每个map需要写入的数据量/每个map任务实际写入数据的执行时间)之和/任务数。Throughput mb/se和这个值的区别在于,前者更能反应总体的吞吐量,后者更照顾每个map的状况,并可以通过IO rate std deviation来反映出不同map之间的写入性能的波动。
  • IO rate std deviation:Average IO rate mb/sec的标准差。
  • Test exec time sec:整个job的执行时间。

吞吐量和平均IO速度计算公式如下所示,最终它们的差别不会很大:

Untitled 1.png

3. HDFS集群压测实践

  1. 压测目的:查看HDFS on Juicefs和HDFS on SSD性能差别以及HDFS on Juicefs的性能瓶颈。
  2. 压测方式:
    1. SliveTest压测RPC。
    2. DFSIO压测读写性能。

3.1 RPC性能压测

在1000个maps中,每个map发送各类RPC请求,如下:

# 1000 并发
hadoop jar hadoop2/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar SliveTest -maps 1000 -ops 10000 -files 1000 -resFile /home/hadoop/tmp/slivetest.txt

观察各种rpc耗时,除了fsimage处理,其他rpc均低于10ms,性能正常:

Untitled 2.png

3.2 读写性能压测

正常写性能

方案:分别在Disk和Juicefs中以1000个map并发,每个map写10GB的文件。

默认HDFS存储策略就是写HDFS。如下,直接写文件到/benchmarks/TestDFSIO 目录中:

# 写文件
hadoop jar hadoop2/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar TestDFSIO -write -nrFiles 1000 -size 10GB -resFile /home/hadoop/tmp/writeres.txt

juicefs标注的时SSD类型,将/benchmarks/TestDFSIO 设置为ALL_SSD策略再执行写入:

# 设置DFSIO目录策略为ALL_SSD
hdfs storagepolicies -setStoragePolicy -path /benchmarks/TestDFSIO -policy ALL_SSD

# 查看目录是否是SSD策略
hdfs storagepolicies -getStoragePolicy -path /benchmarks/TestDFSIO
#写文件
hadoop jar hadoop2/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar TestDFSIO -write -nrFiles 1000 -size 10GB -resFile /home/hadoop/tmp/writeres.txt

通过对比,发现写入磁盘吞吐量为24.8mb/s,写入juicefs吞吐量为18.45mb/s,性能降低25%。

Untitled 3.png

正常读性能

# 读文件
hadoop jar /home/hadoop/hadoop2/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-cdh5.6.0-tests.jar TestDFSIO -read -nrFiles 1000 -size 10GB -resFile /home/hadoop/tmp/readres.txt

通过对比,发现读取磁盘吞吐量为93.98mb/s,写入juicefs吞吐量为80.27mb/s,性能降低14%。

Untitled 4.png

juicefs极限情况下读写性能

5000maps,每个map读写20GB数据。对于写性能,单机带宽打满,S3带宽有空闲。

Untitled 5.png

对于读性能,同样如此:

Untitled 6.png

3.2 总结

写入juicefs相对于写入HDFS,其读写性能下降15%~30%。对于当前测试方案,由于单机带宽和机器数量的限制,未能达到S3带宽上限,无法探测性能上限。对于当前集群,最多能并发处理100TB数据。

方案优化点:

  1. 由于juicefs会经常上传小文件到s3中,因此可以测试op并发上限,这种测试一般由juicefs自身的压测命令执行。
  2. 在压测时,也应该观察HDFS个组件和juicefs性能指标,观察是否发生性能瓶颈。