我刚刚启动了一个新实例,即类型为 i3en.3xlarge 的 ec2 实例。操作系统是 Ubuntu。我安装了 NVMe 实例存储,但我运行的每次速度测试都低得令人难以置信,大约只有 7k iops。我做错了什么?
以下是我执行的步骤:
1)使用 nvme -list 检查可用的 ssd:
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1 vol012301587a8724842 Amazon Elastic Block Store 1 8.59 GB / 8.59 GB 512 B + 0 B 1.0
/dev/nvme1n1 AWS16AAAC6C7BFAC4972 Amazon EC2 NVMe Instance Storage 1 7.50 TB / 7.50 TB 512 B + 0 B 0
2)为nvme1n1创建一个新的xfs文件系统:
sudo mkfs -t xfs /dev/nvme1n1
3)将其挂载到/home
sudo mount /dev/nvme1n1 /home
4)检查df-h:
ubuntu@ip-172-31-35-146:/home$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 7.7G 2.8G 4.9G 37% /
devtmpfs 47G 0 47G 0% /dev
tmpfs 47G 0 47G 0% /dev/shm
tmpfs 9.4G 852K 9.4G 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 47G 0 47G 0% /sys/fs/cgroup
/dev/loop0 25M 25M 0 100% /snap/amazon-ssm-agent/4046
/dev/loop3 43M 43M 0 100% /snap/snapd/14066
/dev/loop2 68M 68M 0 100% /snap/lxd/21835
/dev/loop1 56M 56M 0 100% /snap/core18/2284
/dev/loop4 62M 62M 0 100% /snap/core20/1242
/dev/loop6 56M 56M 0 100% /snap/core18/2253
/dev/loop5 44M 44M 0 100% /snap/snapd/14549
/dev/loop7 62M 62M 0 100% /snap/core20/1328
tmpfs 9.4G 0 9.4G 0% /run/user/1000
/dev/nvme1n1 6.9T 49G 6.8T 1% /home
5)使用 fio 运行测试:
fio -direct=1 -iodepth=1 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
Fio 结果:
fio-3.16
Starting 1 process
Rand_Read_Testing: Laying out IO file (1 file / 1024MiB)
Jobs: 1 (f=1): [r(1)][100.0%][r=28.5MiB/s][r=7297 IOPS][eta 00m:00s]
Rand_Read_Testing: (groupid=0, jobs=1): err= 0: pid=1701: Sat Jan 29 22:28:17 2022
read: IOPS=7139, BW=27.9MiB/s (29.2MB/s)(1024MiB/36717msec)
slat (nsec): min=2301, max=39139, avg=2448.98, stdev=311.68
clat (usec): min=32, max=677, avg=137.06, stdev=26.98
lat (usec): min=35, max=680, avg=139.59, stdev=26.99
clat percentiles (usec):
| 1.00th=[ 35], 5.00th=[ 99], 10.00th=[ 100], 20.00th=[ 124],
| 30.00th=[ 125], 40.00th=[ 126], 50.00th=[ 139], 60.00th=[ 141],
| 70.00th=[ 165], 80.00th=[ 167], 90.00th=[ 169], 95.00th=[ 169],
| 99.00th=[ 172], 99.50th=[ 174], 99.90th=[ 212], 99.95th=[ 281],
| 99.99th=[ 453]
bw ( KiB/s): min=28040, max=31152, per=99.82%, avg=28506.48, stdev=367.13, samples=73
iops : min= 7010, max= 7788, avg=7126.59, stdev=91.80, samples=73
lat (usec) : 50=1.29%, 100=9.46%, 250=89.19%, 500=0.06%, 750=0.01%
cpu : usr=1.43%, sys=2.94%, ctx=262144, majf=0, minf=12
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=262144,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
READ: bw=27.9MiB/s (29.2MB/s), 27.9MiB/s-27.9MiB/s (29.2MB/s-29.2MB/s), io=1024MiB (1074MB), run=36717-36717msec
Disk stats (read/write):
nvme1n1: ios=259894/5, merge=0/3, ticks=35404/0, in_queue=35404, util=99.77%
根据以下基准这里iops 性能应该会更好。
所以我这里遗漏了什么吗?
提前致谢
答案1
因此,我创建了其中一个实例来亲自测试。我的步骤只有一点不同:
- 首先使用以下方法对磁盘进行分区
parted
- 建立文件系统
- 挂载在
/opt
as 处/home
已经存在,并且我的用户的主目录在 (ubuntu
) 中。 apt update && apt upgrade
,然后安装fio
- 运行与您相同的命令:
fio -direct=1 -iodepth=1 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
从内部/opt
,使用sudo
。
我得到了类似的结果,使用read: IOPS=7147
。
然后我又进行了另一项测试:
/opt$ sudo fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=fiotest --filename=testfio --bs=4k --iodepth=64 --size=8G --readwrite=randrw --rwmixread=75
fiotest: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.16
Starting 1 process
fiotest: Laying out IO file (1 file / 8192MiB)
Jobs: 1 (f=1): [m(1)][100.0%][r=332MiB/s,w=109MiB/s][r=85.1k,w=28.0k IOPS][eta 00m:00s]
fiotest: (groupid=0, jobs=1): err= 0: pid=26470: Mon Jan 31 09:14:45 2022
read: IOPS=91.5k, BW=357MiB/s (375MB/s)(6141MiB/17187msec)
bw ( KiB/s): min=339568, max=509896, per=100.00%, avg=366195.29, stdev=59791.96, samples=34
iops : min=84892, max=127474, avg=91548.82, stdev=14947.99, samples=34
write: IOPS=30.5k, BW=119MiB/s (125MB/s)(2051MiB/17187msec); 0 zone resets
bw ( KiB/s): min=111264, max=170424, per=100.00%, avg=122280.71, stdev=20225.33, samples=34
iops : min=27816, max=42606, avg=30570.18, stdev=5056.32, samples=34
cpu : usr=19.73%, sys=41.60%, ctx=742611, majf=0, minf=8
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
issued rwts: total=1572145,525007,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=64
Run status group 0 (all jobs):
READ: bw=357MiB/s (375MB/s), 357MiB/s-357MiB/s (375MB/s-375MB/s), io=6141MiB (6440MB), run=17187-17187msec
WRITE: bw=119MiB/s (125MB/s), 119MiB/s-119MiB/s (125MB/s-125MB/s), io=2051MiB (2150MB), run=17187-17187msec
Disk stats (read/write):
nvme1n1: ios=1563986/522310, merge=0/0, ticks=927244/24031, in_queue=951275, util=99.46%
...看上去好多了- read: IOPS=91.5k
。
我怀疑这是由于只读测试的工作方式所致?还是读取磁盘时的一些细微差别,还是其他限制?
我又进行了几次测试,每次都得到了类似的结果。
然后我使用以下命令运行了另一个只读测试这里,并得到如下结果:
/opt$ sudo fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=fiotest --filename=testfio --bs=4k --iodepth=64 --size=8G --readwrite=randread
fiotest: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.16
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=332MiB/s][r=85.1k IOPS][eta 00m:00s]
fiotest: (groupid=0, jobs=1): err= 0: pid=26503: Mon Jan 31 09:17:57 2022
read: IOPS=88.6k, BW=346MiB/s (363MB/s)(8192MiB/23663msec)
bw ( KiB/s): min=339560, max=787720, per=100.00%, avg=354565.45, stdev=72963.81, samples=47
iops : min=84890, max=196930, avg=88641.40, stdev=18240.94, samples=47
cpu : usr=15.37%, sys=31.05%, ctx=844523, majf=0, minf=72
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
issued rwts: total=2097152,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=64
Run status group 0 (all jobs):
READ: bw=346MiB/s (363MB/s), 346MiB/s-346MiB/s (363MB/s-363MB/s), io=8192MiB (8590MB), run=23663-23663msec
Disk stats (read/write):
nvme1n1: ios=2095751/1, merge=0/0, ticks=1468160/0, in_queue=1468159, util=99.64%
读取性能好多了。我怀疑你给命令提供的参数不允许测试从磁盘获得最佳性能,可能是由于块大小、文件大小等原因。我注意到它们都是单破折号参数(例如-bs=4k
)而不是双破折号(--bs=4k
),所以它们甚至可能没有被正确解析……
答案2
感谢@shearn89 的回复和 aws 支持,我发现我运行 fio 测试的方式是问题所在。
以下是 AWS 告诉我的内容:
首先,实例类型 i3.4xlarge 的列出读/写 IOPS 分别为 825k 和 360k [1]。使用高达 4KB 的块大小和队列深度饱和时,可以获得此 IOPS 性能。
卷队列长度是设备待处理的 I/O 请求数。最佳队列长度因工作负载而异,具体取决于特定应用程序对 IOPS 和延迟的敏感度。如果您的工作负载未提供足够的 I/O 请求来充分利用 EBS 卷可用的性能,则您的卷可能无法提供您预置的 IOPS 或吞吐量 [2]。
为了确定 SSD 卷上工作负载的最佳队列长度,我们建议您将每 1000 IOPS 的队列长度设为 1 [3]。增加队列长度是有益的,直到您达到预置 IOPS、吞吐量或最佳系统队列长度值(当前设置为 32)。有关队列深度的更多信息,请参阅这些第三方文章,其中详细解释了该术语 [4][5][6]。
为了复制您的问题,我启动了相同类型和 AMI 的实例,使用 2 个实例存储 NVMe 设备 [7] 创建了一个 RAID 0 阵列,并使用您提供的相同参数运行了 fio。结果与您实现的结果类似:
$ sudo fio -direct=1 -iodepth=1 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
iops : min= 8820, max= 9196, avg=8905.17, stdev=102.04, samples=58
$ sudo fio -direct=1 -iodepth=1 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
iops : min= 1552, max= 2012, avg=1883.84, stdev=59.06, samples=278
我重复了上述测试,通过设置参数“iodepth=32”和“numjobs=16”,能够分别达到 824k 和 460k 的 R/W IOPS:
$ sudo fio --directory=/mnt/raid --name fio_test_file --direct=1 --rw=randread --bs=4k --size=1G --numjobs=16 --time_based --runtime=180 --group_reporting --norandommap --iodepth=32 --ioengine=libaio
iops : min=572631, max=910386, avg=824619.49, stdev=3518.58, samples=5745
$ sudo fio --directory=/mnt/raid --name fio_test_file --direct=1 --rw=randwrite --bs=4k --size=1G --numjobs=16 --time_based --runtime=180 --group_reporting --norandommap --iodepth=32 --ioengine=libaio
iops : min=291970, max=509505, avg=360163.50, stdev=2193.22, samples=5760
请注意,实例存储 IOPS 还取决于许多因素,包括上面提到的因素,例如 I/O 类型、块大小、I/O 大小、I/O 引擎、I/O 深度、文件/设备数量以及线程/进程数量。有关如何调整参数以优化性能的更多信息,请参阅这些文章 [8][9][10]。
此外,实例存储为你的实例提供临时存储,如果底层磁盘发生故障或实例停止/终止,数据将丢失[11]。因此,如果你需要持久性数据存储,请考虑更持久的选项,例如Amazon EBS [12]。
希望以上信息对您有用。如果您有任何其他技术问题,请告诉我。
谢谢。