背景

SSD介质的特性,决定了其在顺序写、随机写不同模式下的性能表现。那么具体有多少差别呢?能否量化分析这些差别?

理论分析

  • 顺序写和随机写性能的差别出现在物理磁盘第一次写满之后

在全盘 trim之后的第一次写,在磁盘物理空间(包括OP空间)第一次写满之前,顺序写的性能会比随机写性能稍好,因为这个时候空闲地址转换表很多,而且都按照写请求进入的顺序建立逻辑地址到磁盘物理地址的地址转换映射表。

此后,磁盘物理空间写满,逻辑上新来的写都是覆盖写,物理磁盘内部进入高速GC的阶段。对于顺序写触发的覆盖写,一次写触发的擦除操作挣出来的空闲地址转换表大概率能被后续的顺序写利用起来。而随机操作触发的覆盖写,一次写触发的擦除操作挣出来的空闲地址转换表小概率能被后续的随机写利用起来,因此内部GC更加频繁,留给用户的带宽就相对少一些。

实测数据

下面是基于同一款SSD 持续4~5个小时的测试命令:

mkfs.ext4 /dev/nvme2n1
#fio -filename=/dev/nvme7n1 -thread -numjobs=1 -iodepth=16 -direct=1 --rw=randrw -ioengine=libaio -bssplit=20k/90:500k/10 -size=30G -group_reporting -name=perf --output-format=normal --log_avg_msec=1000 --write_bw_log=4k-write.results --write_iops_log=4k-write.results --write_lat_log=4k-write.results --runtime=18000 --time_based
fio -filename=/dev/nvme2n1 -thread -numjobs=1 -iodepth=256 --bs=64K -direct=1 --rw=randwrite -ioengine=libaio --group_reporting -name=perf --output-format=normal --log_avg_msec=1000 --write_bw_log=64k-write.results --write_iops_log=64k-write.results --write_lat_log=64k-write.results --runtime=14400 --time_based

16线程4K 顺序写

SSD 特性探索_第1张图片

可以看到,在物理磁盘第一次写满的时候,性能比较好;写满之后,性能稍差。整体性能也比较均衡。

16线程4K随机写

SSD 特性探索_第2张图片

而对于随机写:在物理磁盘第一次写满的时候,性能比较好;写满之后,性能退化严重。整体性能抖动很大。

  • 基于SSD 裸块设备的读写,比较大的块设备Size 才能够发挥磁盘性能

16线程64K顺序写

SSD 特性探索_第3张图片

由于是顺序写,写满之后的覆盖写触发的GC的效率比较高,因此用户看到的性能持续稳定在标称值范围之内。

16线程64K随机写

SSD 特性探索_第4张图片

比较顺序写和随机写可以看到,同样存在上面的结论:磁盘全部trim之后的第一次写满之前,随机和顺序写性能都不错;写满之后随机写的性能相比顺序写骤降很多,随后缓慢上升,写满之后性能又有骤降,如此循环反复。

  • 如果IO size 合适 1个线程基于裸盘也能充分发挥磁盘性能

1线程64K顺序写

全盘trim之后,即便在1个线程的情况下,64K仍然可以发挥NVME SSD磁盘的良好性能,如下图所示:
SSD 特性探索_第5张图片

1 线程64K随机写

同样测试这么长时间,可以看到随机写还是出现了剧烈的性能下降:

SSD 特性探索_第6张图片

  • 全盘trim之后,随机写性能骤降的时间点和磁盘整体写入量相关,大概是以累计写入量接近物理磁盘可用空间的倍数为周期

下面分别以上面的1 线程64K随机写 的累计写入量和持续写入的时间点关系为例进行说明:
SSD 特性探索_第7张图片

上图中第一个拐点是(2.23e+07,4.33e+09),第二个拐点是(1.01e+07,8.29e+09)。磁盘标称物理空间是4T,默认OP是12%,因此实际物理空间是4000G/(1-12%)= 4545.45G。

结论

理解SSD的性能测试数据,需要深入理解SSD内部的工作原理,才能解释测试得到的数据。