[转帖]从理论到实践,异步I/O模式下NVMe SSD高性能之道

理论,实践,异步,模式,nvme,ssd,高性能 · 浏览次数 : 0

小编点评

**Memblaze简介** Memblaze是一个基于libaio的存储管理引擎,用于数据库、数据库等典型应用场景。它提供了多个介质、接口和协议规范,以帮助用户构建高性能、高能源效率的存储系统。 **主要功能** * 支持多个介质:数据库、数据库等典型应用场景。 * 提供多个接口:libaio、Memcached、Memblaze等。 * 支持多种协议规范:TCP、UDP、Memcached等。 * 提供多种优化工具:配置、性能峰值等。 **优势** * 高性能:支持多个介质、接口和协议规范。 * 高能源效率:提供多种优化工具,以帮助用户构建高性能、高能源效率的存储系统。 * 易于使用:提供多种接口,以帮助用户快速构建存储系统。 **应用场景** * 数据库 * 存储引擎 * 数据库等典型应用场景 **性能峰值** * 512(numjobs*iodepth)

正文

在早期NVMe的讨论话题中,常常将之AHCI协议进行对比,在支持的最大队列深度、并发进程数以及消耗时钟周期数等方面,NVMe吊打了AHCI。最直观也最权威的就是下面这张对比图片。

在这里插入图片描述
NVMe与AHCI协议对比(来源:sata-io.org

SATA的发展最早可以追溯到上世纪80年代的IDE/ATA,在HDD时代是硬盘最主流的存储接口。SATA Express采用AHCI协议将硬盘映射成一个PCIe设备以提高系统性能。但是第三代SATA的带宽也只有6Gb/s,无法彻底释放闪存的性能。当SSD接口由SATA被PCIe取代之后,一个更加高效的存储接口协议诞生是必然,这就是NVMe。(更多细节可以看文末相关阅读文章)

PCIe和NVMe组合提高了SSD的性能上限,一块SATA SSD无论如何带宽也不会突破1GB/s以及稳定的微秒级延迟。是否能达到这个上限,就需要看SSD本身的软硬件设计水平了。

NVMe SSD的高性能可以直接反映到测试基准测试的结果上,需要注意的是测试NVMe SSD的特点是遇强则强,需要高压力方可看到性能效果。接下来就是用fio通过几组测试来解读NVMe SSD的性能优势。当然,这些测试也将为系统性能优化提供理论基础。

在写fio脚本之前,还需要注意同步I/O和异步I/O的概念,这也是本文测试压力模型中的重要变量。同步I/O是指系统的一个线程一次只能发出一个I/O,等待内核处理完成才返回结果,系统再发下一个I/O。异步I/O模式是系统的线程不停的发I/O直到达到设置的队列深度上限,此期间,线程SSD通知会通过中断或者轮询等方式告诉CPU,CPU来调用该命令的回调函数来处理结果。原生的异步I/O技术以Linux下的libaio和Windows下的windowsaio最为常见。

测试软件:fio
NVMe SSD:PBlaze5 910 7.68TB

依据同步I/O和异步I/O的原理,我们可以总结出几个结论。

第一:同步模式下增加I/O队列深度并不能得到更高的性能,因为其机制只能1次发1个I/O。而通过增加线程数才可以获得更大的压力;

第二:异步I/O模式可以通过调整队列深度提升压力,例如同步模式下32个线程并发和异步I/O模式下1个线程32队列深度的测试结果应当相同,而且通过提高线程数异步I/O模式可以进一步提高压力;

第三,对于高性能的NVMe SSD,使用异步I/O模式更容易获得高性能收益。

使用fio可以方便的选择I/O引擎并对并发进程数和队列深度等参数进行设置。接下来就是验证上面的三个观点。验证测试前,我们需要先进行预处理,全盘顺序写2遍然后随机写4个小时,命令如下:

fio --ioengine=libaio --direct=1 --thread --norandommap --filename=/dev/nvme1n1 --name=init_seq2 --output=init_seq2.log --rw=write --bs=128k --numjobs=1 --iodepth=128 --loops=2
fio --ioengine=libaio --direct=1 --thread --norandommap --filename=/dev/nvme1n1 --name=init_rand --output=init_rand.log --rw=randwrite --bs=4k --numjobs=8 --iodepth=64 --ramp_time=60 --runtime=14400

1、 使用同步io模式,我们测出了一组数据,并取得了IOPS的值。如下:

fio --ioengine=psync --randrepeat=0 --norandommap --thread --direct=1 --group_reporting --name=mytest --ramp_time=1 --runtime=432 --time_based --numjobs=8 --iodepth=1 --filename=/dev/nvme0n1 --rw=randread --bs=4k

我们改变下iodepth和numjobs,测几组不同的值对比。
在这里插入图片描述
可以看到当相同的numjobs参数下,SSD的IOPS性能处于同一水平,只有改并发进程数会改变性能。这验证了我们前文中的第一个观点,接下来我们将测试的重点放在异步IO模式下的测试。

本次系列测试均为4K随机读测试,nubjobs(并发进程数)和iodepth(队列深度)是各测试的两个主要变量,可以说两者的乘积决定了各组测试的压力大小。而psync(同步IO模式)和libaio(异步IO模式)决定了大于1的iodepth是否有效。

2、 异步I/O、队列深度:64、并发线程数:8

fio --ioengine=libaio --randrepeat=0 --norandommap --thread --direct=1 --stonewall --group_reporting --name=mytest --ramp_time=60 --runtime=600 --time_based --numjobs=8 --iodepth=64 --filename=/dev/nvme1n1 --rw=randread --bs=4k --output=256-4K_randR512.log

测试结果如下(IOPS:1007.5k):

mytest: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=64

fio-2.2.9
Starting 8 threads
mytest: (groupid=0, jobs=8): err= 0: pid=11418: Sun May 5 17:24:27 2019
read : io=2305.1GB, bw=3935.5MB/s, iops=1007.5K, runt=600001msec
slat (usec): min=1, max=340, avg= 3.54, stdev= 1.72
clat (usec): min=21, max=2204, avg=504.18, stdev=183.15
lat (usec): min=23, max=2208, avg=507.85, stdev=183.15
clat percentiles (usec):
| 1.00th=[ 177], 5.00th=[ 233], 10.00th=[ 278], 20.00th=[ 338],
| 30.00th=[ 390], 40.00th=[ 442], 50.00th=[ 490], 60.00th=[ 540],
| 70.00th=[ 596], 80.00th=[ 660], 90.00th=[ 756], 95.00th=[ 828],
| 99.00th=[ 972], 99.50th=[ 1032], 99.90th=[ 1144], 99.95th=[ 1208],
| 99.99th=[ 1336]
bw (KB /s): min= 0, max=511944, per=12.49%, avg=503317.68, stdev=14677.46
lat (usec) : 50=0.01%, 100=0.01%, 250=6.73%, 500=45.53%, 750=37.48%
lat (usec) : 1000=9.52%
lat (msec) : 2=0.74%, 4=0.01%
cpu : usr=11.86%, sys=62.31%, ctx=194475883, majf=0, minf=17716
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=109.9%
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 : total=r=604477416/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0
latency : target=0, window=0, percentile=100.00%, depth=64
Run status group 0 (all jobs):
READ: io=2305.1GB, aggrb=3935.5MB/s, minb=3935.5MB/s, maxb=3935.5MB/s, mint=600001msec, maxt=600001msec
Disk stats (read/write):
nvme1n1: ios=664494451/0, merge=0/0, ticks=330657118/0, in_queue=18446744069786846278, util=100.00%

我们同样获取了libaio模式下的多组数据,如下表:在这里插入图片描述
如下图可以看到,numjobs和iodepth组合下压力越大,性能也越高。最终在512(numjobs*iodepth)时达到了PBlaze5的性能峰值。
在这里插入图片描述
不同的介质、不同的接口和协议规范对于测试以及采购、配置、优化和升级的各项工作有着重要意义,也是以最小的成本获取最高性能的前提。Memblaze一直致力于帮助用户构建高性能、高能源效率的存储系统,针对数据库等典型应用场景还有着更为定制化的方案。

参考

fio howto

</article>

与[转帖]从理论到实践,异步I/O模式下NVMe SSD高性能之道相似的内容:

[转帖]从理论到实践,异步I/O模式下NVMe SSD高性能之道

在早期NVMe的讨论话题中,常常将之AHCI协议进行对比,在支持的最大队列深度、并发进程数以及消耗时钟周期数等方面,NVMe吊打了AHCI。最直观也最权威的就是下面这张对比图片。 NVMe与AHCI协议对比(来源:sata-io.org) SATA的发展最早可以追溯到上世纪80年代的IDE/ATA,

[转帖]从性能问题定位,扯到性能模型,再到 TCP - 都微服务云原生了,还学 TCP 干嘛系列 Part 1

https://blog.mygraphql.com/zh/posts/low-tec/network/tcp-flow-control-part1/ 引 本来想直接写理论、和实践分析的,但为了不 “赶客出門” 和不 TL;DR,还是以故事形式展开吧。语言要生动活泼。 故事的开始 话说,一次性能测试

[转帖]linux 上实现 vxlan 网络

https://cizixs.com/2017/09/28/linux-vxlan/ linux 上 vxlan 简介 vxlan 协议的介绍文章主要介绍了 vxlan 协议的理论知识,从产生的背景到报文的格式等等,和所有的计算机知识一样,理论必须结合实践理解才能更深刻,这篇文章我们就讲讲在 lin

[转帖]K8S从懵圈到熟练 – 集群服务的三个要点和一种实现

https://developer.aliyun.com/article/711580?spm=a2c6h.13262185.profile.81.32d83219xsvxWd 以我的经验来讲,理解K8S集群服务的概念,是比较不容易的一件事情。尤其是当我们基于似是而非的理解,去排查服务相关问题的时候

[转帖]深入理解mysql-第六章 mysql存储引擎InnoDB的索引-B+树索引

一、引入索引 在没有索引的情况下,不论是根据主键列或者其他列的值进行查找,由于我们并不能快速的定位到记录所在的页,所以只能从第一个页沿着双向链表一直往下找,因为要遍历所有的数据页,时间复杂度就是O(n),所以这种方式显然是超级耗时的。所以我们需要采取一定的数据结构来存储数据,方便我们进行数据的增删改

[转帖]awk——getline

http://t.zoukankan.com/panscience-p-4685698.html A.getline从整体上来说,应这么理解它的用法: 当其左右无重定向符 | 或 < 时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量var 或$0(无变量);应该注意到,由于awk

[转帖]从Linux零拷贝深入了解Linux-I/O

https://aijishu.com/a/1060000000375591 作者:kevineluo,腾讯 CSIG 后台开发工程师 本文将从文件传输场景以及零拷贝技术深究 Linux I/O 的发展过程、优化手段以及实际应用。 前言 存储器是计算机的核心部件之一,在完全理想的状态下,存储器应该要

[转帖]「理解C++20协程原理」从Linux线程、线程与异步编程、协程与异步

协程不是系统级线程,很多时候协程被称为“轻量级线程”、“微线程”、“纤程(fiber)”等。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速切换。 协程和用户态线程非常接近,用户态线程之间的切换不需要陷入内核,但部分操作系统中用户态线程的切换需要内核态线程的辅助。 协程是编程语言(或

[转帖]DISK BUSY的理解误区

前几天有个客户的系统存在性能问题,从AWR报告上我们看到是CPU使用率过高,同时GLOBAL CACHE方面的争用比较严重。系统中的烂SQL很多,数据库中很多几十GB的大表也没有分区,总之问题很多。不过这套系统使用了闪存盘,虽然IOPS高达3-4万,不过磁盘IO的性能还可以。USER IO平均值为2

[转帖]Linux性能分析(二):理解CPU上下文切换

在计算机中,上下文切换是指存储进程或线程的状态,以便以后可以还原它并从同一点恢复执行。这允许多个进程共享一个CPU,这是多任务操作系统的基本功能。 Linux 是一个多任务操作系统,它支持远大于 CPU 数量的任务同时运行,这依赖于CPU上下文切换。CPU 上下文切换,就是先把前一个任务的 CPU