NAS 硬盘性能测试
简介
现在的 NAS 一般是支持固态硬盘和机械硬盘的,固态硬盘适合用于安装系统、创建缓存、安装程序、Docker 和虚拟机,机械硬盘适合用于大量冷资源备份存储。
固态硬盘和机械硬盘,raid 和单盘性能之间的差距,想要了解这些就需要硬盘性能测试,windows 系统下有许多测试软件如 CrystalDiskMark、AS SSD Benchmark、HD Tune 等,各种 NAS 系统却没有专业的测试工具。多数 NAS系统都是基于 Linux 开发的,我们可以使用 SSH 登入系统使用 dd 命令或者安装专业的测试工具如 fio 进行测试。
性能指标
顺序读写
顺序读写比较好理解,顾名思义就是将要处理的数据集中起来排好队,按照最优化的速度进行连续读写,通常在读写大型文件时可以获得比较理想的顺序读写速度,适用场景:大文件拷贝(比如视频音乐),速度即使很高,对数据库性能也没有参考价值。
随机读写
随机读写的特征在于读写具有随机性,不遵循文件的先后顺序进行数据的读取和写入,可任意跳到某个文件节点处进行读写操作。
4k读写
要理解什么是4k读写,首先要理解这里的4k是指什么。这里的4K指的是文件的最小占用是4kb,是windows下最小的文件占用空间,那么4k读写性能其实就是针对小文件的读写性能。适用场景:操作系统运行、软件运行、数据库。
IOPS
随机读写性能是固态硬盘的关键指标,其单位为IOPS(Input/Output Operations Per Second),即每秒进行读写(I/O)操作的次数,它在某种程度上影响着数据存取会不会卡顿。IOPS值越高,意味着4k读写速度会更快一些。
DD 测试命令
dd 命令可以简单测试硬盘的顺序读写能力,登录 SSH 客户端,输入相关命令,根据输出结果查看硬盘读写性能。
dd 命令通用语法格式如下:
dd if=path/to/input_file of=/path/to/output_file bs=block_size count=number_of_blocks iflag=FLAGS
- if=file 输入文件名,缺省为标准输入
- of=file 输出文件名,缺省为标准输出
- bs=bytes 同时设置读写块的大小为 bytes
- count=blocks 仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数
- iflag=FLAGS 指定读的方式FLAGS,参见“FLAGS参数说明”
- oflag=FLAGS 指定写的方式FLAGS,参见“FLAGS参数说明”
if=/dev/zero(产生字符)不产生 IO,因此可以用来测试纯写速度;同理 of=/dev/null(回收站、无底洞)不产生 IO,可以用来测试纯读速度。FLAGS 参数说明:direct 读写数据采用直接 IO 方式,将跳过内存缓存;dsync 读写数据采用同步IO;sync 同上,但是针对是元数据。
测试纯写入性能
dd if=/dev/zero of=test bs=1024k count=1000 oflag=direct
测试写入1G的数据,会在当前目录下生成一个1G大小的文件,根据输出结果查看速度
测试纯读取性能
dd if=test of=/dev/null bs=1024k count=1000 iflag=direct
测试读取1G的数据,读取当前目录下的test文件,根据输出结果查看速度
测试示例
我的 NAS 系统是群晖系统,有 SATA 机械硬盘、M2 固态硬盘,可以分别进入硬盘所在目录进行测试,
首先测试 SATA 机械硬盘,登录 SSH,输入下面命令进入机械硬盘目录,volume6
是我的群晖硬盘挂载目录,
cd /volume6
输入下面命令测试,测试写入 5G 文件用时,会在当前目录生成 5G 大小的 test 文件,
dd if=/dev/zero of=test bs=1024k count=5000 oflag=direct
输入下面命令测试,测试读取 5G 文件用时,
dd if=test of=/dev/null bs=1024k count=5000 iflag=direct
根据测试结果看到的机械硬盘读取 241MB/s,写入214MB/s。
这是 M2 固态硬盘的测试结果,M2 固态跑在 PCIE3.0x1 通道,速度还算正常,
FIO 测试命令
大部分 NAS 系统无法直接安装 fio,为了方便可以使用 Docker 运行一个 ubuntu/debian 容器进行测试,docker 容器存储性能损耗很小,可以直接当做真实硬盘的性能测试。使用 fio 测试时,注意不要用 fio 测试裸盘,它会损坏你的分区(包括 LVM),不要在任何有文件的地方写,因为它会覆盖写。
添加 debian 容器
添加一个 debian docker容器,可以在 NAS 操作系统中 Docker 管理器中添加,也可以登录 SSH 使用命令行操作,下面介绍一下在 SSH 终端使用命令行操作的步骤,关于无法下载镜像的网络问题请看关于改善 Docker 网络的文章。
登录 SSH,运行以下命令添加 debian 容器
docker run -it --privileged -v /主机路径:/mnt debian /bin/bash
- docker run: Docker 创建并启动一个容器。
- it: 结合了 -i(保持标准输入打开)和 -t(分配伪终端),允许你在终端中以交互模式运行容器。
- privileged:该命令会以特权模式运行容器,容器内的进程几乎拥有与宿主机 root 用户相同的权限。
- v:映射主机目录到容器,测试哪个盘就把哪个盘的路径做下映射。
- debian: 指定要使用的镜像。
- /bin/bash: 在容器中启动一个 bash shell。
下面是我的示例,映射了两个硬盘进行测试,一个是 SATA 机械硬盘,一个是 M2 固态硬盘,建议在测试的硬盘新建一个测试目录,不要在使用中有文件的目录映射。
docker run -it \
--name=debian \
--privileged \
-v /volume1/satatest:/mnt/satatest \
-v /volume4/m2test:/mnt/m2test \
docker.1ms.run/library/debian /bin/bash
使用 docker exec 进入容器
docker exec 命令允许你在容器内启动一个新的终端会话,并在其中执行命令。使用 docker exec 进入容器后,即使退出终端,容器也不会停止运行。
查询容器 ID
sudo docker ps
docker exec 进入容器
docker exec -it 容器ID /bin/bash
安装 fio
更新 debian 的软件源
apt update
等待更新完成后,安装fio
apt install fio
期间提示是否继续安装,输入 Y 继续,等待一会安装完成,
注意:
在国内环境执行更新安装操作可能会比较慢,可以修改国内软件源改善网络,但由于默认镜像是没有 vi/vim 编辑命令,可以使用下面的 echo 命令添加阿里云源,然后执行更新安装操作。
echo 'deb https://mirrors.aliyun.com/debian/ bookworm main non-free non-free-firmware contrib' >> /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/debian/ bookworm main non-free non-free-firmware contrib' >> /etc/apt/sources.list && \
echo 'deb https://mirrors.aliyun.com/debian-security/ bookworm-security main' >> /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/debian-security/ bookworm-security main' >> /etc/apt/sources.list && \
echo 'deb https://mirrors.aliyun.com/debian/ bookworm-updates main non-free non-free-firmware contrib' >> /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/debian/ bookworm-updates main non-free non-free-firmware contrib' >> /etc/apt/sources.list && \
echo 'deb https://mirrors.aliyun.com/debian/ bookworm-backports main non-free non-free-firmware contrib' >> /etc/apt/sources.list && \
echo 'deb-src https://mirrors.aliyun.com/debian/ bookworm-backports main non-free non-free-firmware contrib
' >> /etc/apt/sources.list
安装完国内源更新可能会出现证书验证问题,解决办法:
1.把源 https 协议换成 http 协议,
2.先安装 certificate 库(安装命令为 apt install ca-certificates),再修改成阿里云的源地址。
执行测试
顺序读测试
使用下面命令测试顺序读吞吐能力,-directory=/mnt
修改成自己的挂载目录,
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 --rw=read -bs=1M -size=1G -time_based -runtime=30 -name=Fio -directory=/mnt
我的测试结果如下,根据输出结果可以看到读写速度和 IOPS 值,
顺序写测试
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=write -bs=1M -size=1G -time_based -runtime=30 -name=Fio -directory=/mnt
我的测试结果如下:
4K 随机读 IOPS
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randread -bs=4K -size=1G -time_based -runtime=30 -name=Fio -directory=/mnt
我的测试结果如下:
4K 随机写 IOPS
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randwrite -bs=4K -size=1G -time_based -runtime=30 -name=Fio -directory=/mnt
我的测试结果如下:
随机读吞吐
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randread -bs=1M -size=1G -time_based -runtime=30 -name=Fio -directory=/mnt
我的测试结果如下:
随机写吞吐
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randwrite -bs=1M -size=1G -time_based -runtime=30 -name=Fio -directory=/mnt
我的测试结果如下:
参数解释
numjobs
:表示测试的并发线程数。iodepth
:表示测试时的IO队列深度。direct
:表示是否使用direct I/O,默认值:1。值为1:表示使用direct I/O,忽略I/O缓存,数据直写。ioengine
:表示测试时FIO选择哪种I/O引擎,通常选择libaio,更符合日常应用模式。rw
:表示测试时的读写策略。您可以设置为:- randwrite:随机写。
- randread:随机读。
- read:顺序读。
- write:顺序写。
- randrw:混合随机读写。
bs
:表示I/O单元的块大小(block size)size
:表示测试文件大小。time_based
:基于时间运行测试。runtime
:表示测试时间,即FIO运行时长。name=Fio
:测试任务名称。
使用测试脚本(YABS)
YABS 脚本是使用 fio、iperf3 和 Geekbench 测试 Linux 服务器性能的简单 bash 脚本。我们可以在运行脚本时添加参数单独测试磁盘读写能力,相对于使用 fio 命令有一个比较直观的输出结果。输出结果会分别列出在块大小为 4k、64k、512K、1M 情况下的磁盘读写和 IOPS。
Github 地址:https://github.com/masonr/yet-another-bench-script
使用方法:
进入 debian 容器,先输入下面命令安装 curl
apt update
apt install curl
输入下面命令进入要测试的硬盘挂载目录,按自己情况修改,
cd /mnt/xxx
输入以下代码进行测试,只看 fio 测试结果即可。
curl -sL https://yabs.sh | bash -s -- -i -g
我的测试结果如下,