存储系统的三大性能指标
一个存储系统的性能最主要的是三个:IOPS、访问延迟、吞吐率/带宽。这三个指标其实是相互关联和影响的,但是我们一般还是分块来衡量。
IOPS(Input/Output Per Second),即每秒钟能处理的读写(IO)请求数,这是衡量存储性能的主要指标之一。每个IO请求都有自己的特性,比如读还是写,是顺序读写还是随机读写、IO的大小是多少等。因为IO有这些特点,所以我们讨论存储系统IOPS性能的时候,经常需要更加具体的模式,比如顺序IOPS、随机写IOPS等。IOPS的数值会随这样的参数不同而有很大的不同,这些参数的变化,包括读取和写入的比例,其中顺序读写以及随机读写的比例、读写大小、线程数量和读写队列深度等。此外,系统配置等因素也会影响IOPS的结果,比如操作系统的设置、存储设备的驱动程序特点、操作系统后台运行的作用等。吞吐率和带宽,衡量的是存储系统的实际数据传输速率,通常以MB/s或者GB/s为单位。吞吐量/率:每秒的IO请求大小一般来讲,IOPS和吞吐率是紧密相关的,它们之间的关系是,吞吐率等于IOPS和IO大小的乘积这个也很容易理解,比如对一个硬盘的读写 IO 是 1MB,硬盘的 IOPS 是 100,那么硬盘总的吞吐率就是 100MB/s。需要强调的是,这里 IO 的具体特性很重要,比如是顺序还是随机,IO 大小等。访问延迟和响应时间:IO请求从发出到收到响应的间隔时间:常以毫秒ms或者微秒us为单位。对这一性能指标,我们通常会考虑它的平均值和高位百分数,比如P99,P95。另外,有些存储系统会因为其IO队列深度增加,而获得更好的IO性能。比如吞吐率会升高,平均访问延迟会降低。 这是因为存储系统的IO队列处理机制,可以对IO进行重新排序,从而获得更好的性能。比如,它可以合并几个相邻的IO、把随机IO重新排序为顺序IO等
注意:我们可能还需要关注如下项目:
使用率,是指磁盘处理IO的时间百分比。过高的使用率(比如超过80%),通常意味着磁盘IO存在性能瓶颈使用率只考虑有没有IO,而不考虑IO的大小。换句话说。当使用率是100%时,磁盘依然有可能接收新的IO请求。使用率和饱和度是完全不同的对于一个系统IO来说,需要把磁盘IO指标和文件系统IO指标区分开
下面是磁盘IO指标:
测试
说明
重要程度
怎么测试
哪些需要
异常值
IO读写延迟 / 响应时间
IO请求从发出到收到响应的间隔时间
最基本,必备
一般是用4KB大小的IO做基准来测试
单个磁盘、磁盘阵列、网络磁盘等必须
IO带宽
最基本,必备
一般是针对比较大的IO而言
单个磁盘、磁盘阵列、网络磁盘等必须
IOPS
每秒钟能处理的读写(IO)请求数
最基本,必须
对于HDD来说,一般为120;对于SSD(SATA)来说,一般为30K;对于SSD(NVMe),一般为400K
饱和度
磁盘处理IO的繁忙程度
非必须
磁盘
过高说明磁盘IO瓶颈。当饱和度为100%时,磁盘无法接收新的IO请求
使用率
磁盘处理IO的时间百分比
非必须
磁盘
过高说明磁盘IO瓶颈,经验值80%
吞吐量 /率
每秒的IO请求大小
下面这个表格列出了几种存储介质和它们的性能数值。
存储
根据存储介质分类
磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类,机械磁盘和固态磁盘
HDD(传统硬盘)
机械磁盘,也叫做硬盘读写器(hard disk driver),通常缩写为HDD。
机械磁盘主要由盘片和读写磁头组成,数据就存储在盘片的环状磁道中。在读写数据前,需要移动读写磁头,定位到数据所在的磁道,然后才能访问数据显然,如果IO请求刚好连续,那就不需要磁盘寻址,自然可以获得最佳性能,这种方式就是连续(顺序)IO的原理。与之对应的就是随机IO,它需要不停的移动磁头,来定位数据位置,所以读写速度会比较慢工作原理:
当应用程序发出硬盘IO请求后,这个请求就会进入硬盘的IO队列。如果前面有其他IO,那么这个请求可能需要排队等待当轮到这个IO来存取数据时,磁头需要机械运动到数据存放的位置,这就需要磁头寻址到相应的磁道,并旋转到相应的扇区,然后才是数据的传输所以,讨论到磁盘IO的性能时,需要充分考虑到这一点。我们有时候需要把硬盘响应时间和硬盘访问时间分别对待。如下图,【硬盘响应时间 = 硬盘访问时间 + IO排队延迟】
我们如果拿起一块硬盘仔细看看,硬盘上面往往会标注后面三个参数,分别是平均寻址时间、盘片旋转速度,以及数据传输速度,这三个参数就可以提供给我们计算上述三个步骤的时间。
平均寻址时间一般是几个毫秒。平均旋转时间可以从硬盘转动速度 RPM 来算出。因为每个IO 请求平均下来需要转半圈,那么如果硬盘磁头每分钟转一万圈(10K RPM),转半圈就需要 3 毫秒。要注意的是,硬盘上面标注的数据传输速度参数往往是最大值,实际的数据传输时间要取决于 IO 的大小。对一块普通硬盘而言,随机IO读写延迟是8毫秒,IO带宽大约100MB/秒,随机IOPS一般在100左右。
硬盘技术也在发展。比如采用了多磁头技术,或者几块硬盘组成磁盘阵列,这样的整体IO性能也会提升。
SSD(固态磁盘)
固态磁盘(solid state disk),通常也叫做SSD,有固态电子元器件组成。固态磁盘不需要磁道寻址,所以,不管是连续IO,还是随机IO的性能,都比机械磁盘要好得多单元(cell)、页面(page)、块(block)
当今主流SSD是基于NAND的,它是将数字位存储在单元中。每个SSD单元可以存储一位(SLC,Single Level Cell,单级单元)、两位(MLC,多级单元)、三位(TLC,三级单元)、四位(QLC)SSD的特点是,对SSD单元的每次擦除,都会降低单元的寿命,因此每一个单元只能承受一定数量的擦除。所以,不同的SSD都有这几方面的考虑和平衡。单元存储的位数越多,制造成本越少,SSD容量越大。但是耐久性(擦除次数)也会降低。所以高端SSD,比如企业级的,基本都是基于SLC的一个页面包括很多单元,典型的页面大小是4KB。页面也是读写的最小存储单位我们知道,HDD可以直接对任何字节重写和覆盖;但是对SSD而言,不能直接“覆盖”操作。SSD的一个页面里面的所有单元,一旦写入之后就不能进行重写,必须和其他相邻页面一起,被整体擦除、重置。在SSD内部,多个页面会组成快。一个块的典型大小为512KB或者1MB,也就是大约128或者256页。块是擦除的基本单位,每次擦除,都是整个块内的所有页面都被重置IO和垃圾回收
对SSD的IO操作,一共有三种类型:读取、写入、擦除。
读取和写入是以页为单位的,也就是说最少也要读取写入一个页面IO写入的延迟,具体取决于磁盘的历史状态。因为如果SSD已经存储了很多数据,那么对页的写入,有时需要移动已有的数据,这种情况下写入延迟就比较大。但多数情况下,读写延迟都很低,一般在微秒级别,远低于HDD擦除是以块为单位的。擦除的速度相对较慢,一般为几毫秒所以,对同步的IO请求,发出IO的应用程序,可能会因为块的擦除而经历很大的写入延迟为了建立减少这样的场景发生,一块SSD最好保持一定数量的空闲块,这样可以保证SSD的写入速度足够快。SSD内部由垃圾回收(GC)机制,它的目的就在于此,就是不断回收不用的块,进行擦除,从而产生新的空闲块来备用。这样可以确保以后的页写入能快速分配到一个全新的页写入放大(write amplification,WA)
这是SSD相对于HDD的一个缺点,即实际写入SSD的物理数据量,有可能是应用层写入数据量的多倍。
这是因为,一方面页级别的写入需要移动已有的数据来腾空页面来写入。另一方面,GC的操作,也会移动用户数据来进行块级别的擦除。
所以,对SSD真正的写操作的数据,肯定比实际写的数据量大,这就是写入放大。因为一块SSD只能进行有限的擦除次数,也即编程/擦除(P/E)周期,所以写入放大效应会缩短SSD的寿命。
损耗平衡
对每一个块而言,一旦擦除造成的损耗达到最大数量,该块就会“死亡”,再也不能存储数据了。对于 SLC 类型的块,P/E 周期的典型数目是十万次;对于 MLC 块,P/E 周期的数目是一万;而对于 TLC 块,则可能是几千。为了确保整块 SSD 的容量、性能和可靠性,SSD内部需要对整个 SSD 的各块做平衡,尽量在擦除次数上保持类似。
SSD控制器具有这样一种机制,“损耗平衡”:数据在各个块之间游动,以实现均衡的损耗。这种机制的害处在于会对前面的“写入放大”推波助澜
缺陷
性能方面,SSD 的 IO 性能相对于 HDD 来说,IOPS 和访问延迟提升了上千倍,吞吐率也是提高了几十倍。但是 SSD 的缺点也很明显。主要有三个缺点:
贵容量小一损耗好消息是,随着技术的发展,这三个缺点近几年在弱化。
与 HDD 相比,采用 SSD 带来了极大的应用程序性能提升。但是,在大多数采用 SSD 的部署方案中,SSD 仅被视为一种“更快的HDD”,并没有真正发挥 SSD 的潜力。
为什么这么说呢?
因为尽管使用 SSD 作为存储时,应用程序可以获得更好的性能,但是这些收益,主要归因于 SSD 提供的更高的 IOPS 和带宽。但是,SSD 除了提供这些之外,它还有其它特点,比如易损耗,以及其独特的内部机制。如果应用程序的设计能充分考虑 SSD 的内部机制,设计出对 SSD 友好的应用程序,就可以更大程度地优化 SSD,从而进一步提高应用程序性能,也可以延长 SSD 的寿命,并降低运营成本。小结: 随机IO与连续IO的反应
其实,无论是机械磁盘,还是固态磁盘,相同磁盘的随机IO都要比连续IO慢很多,原因也很明显:
对于机械磁盘来说,由于随机IO需要更多的磁头寻道和盘片旋转,它的性能自然要比连续IO慢对于固态磁盘来说,虽然它的随机性能比机械硬盘要好很多,但同样存在“先擦除再写入”的限制。随机读写会导致大量的垃圾回收,所以相对应的,随机IO的性能比起连续IO来,也还是要差了很多此外,连续IO还可以通过预读的方式,来减少IO请求的次数。这也是其性能优异的一个原因。很多性能优化的方案,也都会从这个角度出发,来优化IO性能。此外,机械磁盘和固态磁盘还分别有一个最小的读写单位。
机械磁盘的最小读写单位是扇区,一般大小为512字节固态磁盘的最小读写单位是页,通常大小是4KB、8KB等如果每次都读写512字节这么小的单位的话,效率很低。
所以,文件系统会把连续的扇区或者页,组成逻辑块,然后以逻辑块作为最小单位来管理数据。常见的逻辑块的⼤⼩是4KB,也就是说,连续8个扇区,或者单独的⼀个⻚,都可以组成⼀个逻辑块。按照接口来分类
除了可以按照存储介质来分类,另一个常见的分类方法,是按照接口来分类,比如可以把硬盘分为 IDE(Integrated Drive Electronics)、SCSI(Small Computer System Interface) 、SAS(Serial Attached SCSI) 、SATA(Serial ATA) 、FC(Fibre Channel) 等。
不同的接口,往往分配不同的设备名称。比如,
DE 设备会分配⼀个 hd 前缀的设备名SCSI和SATA设备会分配⼀个 sd 前缀的设备名。如果是多块同类型的磁盘,就会按照a、b、c等的字⺟顺序来编号。按照使用方式分类
除了磁盘本身的分类外,当你把磁盘接入到服务器后,按照不同的使用方式,又可以把他们分为不同的架构。
也就是可以将磁盘配置成不同的架构,比如磁盘阵列(RAID)
最简单的,就是直接作为独立磁盘设备来使用。这些磁盘,往往还会根据需要,划分为不同的逻辑分区,每个分区再用数据编号。⽐如我们前⾯多次⽤到的 /dev/sda ,还可以分成两个分区 /dev/sda1和/dev/sda2。另一个比较常用的架构,是把多个磁盘组合成一个逻辑磁盘,构成冗余独立磁盘阵列,也就是RAID(Redundant Array of Independent Disks),从而可以提高数据访问的性能,并且增强数据存储的可靠性
根据容量,性能和可靠性不同,RAID一般可以划分为多个级别,如RAID0、RAID1、RAID5、RAID10等。 RAID0有最优的读写性能,但不提供数据冗余的功能而其他级别的RAID,在提供数据冗余的基础上,对读写性能也有一定的优化最后一种架构,是把这些磁盘组合成一个网络存储集群,再通过NFS、SMB、ISCS等网络存储协议,暴露给服务器使用。前面所诉的存储硬件可以直接安装在服务器上,构成单机系统。和单机系统相对应的是,有很多非单机使用的场景。在非单机使用的场景里,这些存储硬件也被包装在各种基于网络的存储系统里。这样的存储系统也有很多种:DAS(Directed Attached Storage)是直连式存储,这是以服务器为中心的存储系统,存储设备直接通过IO总线连在服务器主机上。这种存储一般运行SATA或者SAS等协议,可以让网络的客户端直接使用NAS(Network Attached Storage)是网络接入系统。在NAS存储结构中,存储系统不再通过IO总线只属于某个特定的服务器,而是通过网络接口直接与网络相连。NAS提供的是文件服务器的功能(比如NFS和CIFS),供客户通过网络访问SAN(Storage Area Network)是存储区域网络。SAN是一种以网络为中心的存储系统,通常有高性能专用网络(比如光纤)来支持,运行iSCSI等协议工具
Linux系统上可以采用fio工具来进行各种组合的IO测试,这些组合包括读写比例、随机/顺序读写等IOMeter可以测试磁盘性能,比如IO传输速度、平均IO响应时间IOZone是一个文件系统基准测试工具,可以测试不同的操作系统中文件系统的读写性能Bonnie++是基于Linux平台的开源磁盘IO测试的工具,可以用它来测试磁盘和文件系统的IO性能hdparm可以用来做跳过文件系统的纯硬件操作测试iostat可以查看进程发出的IO请求的数量、系统处理IO请求的耗时、磁盘的利用率等,也可以分析进程和操作系统的交互过程中IO方面是否存在瓶颈。如何对磁盘进行基准测试
磁盘的性能指标
如何衡量磁盘性能?一般从使用率、饱和度、IOPS、吞吐量以及响应时间来看
基准测试
说明
是否必须
使用率
磁盘处理IO的时间百分比(过高说明IO瓶颈,经验值80%)
饱和度
磁盘处理IO的繁忙程度(过高说明IO瓶颈)
IOPS
每秒的IO请求数
吞吐量 /率
每秒的IO请求大小
响应时间/访问延迟
IO请求从发出到收到响应的间隔时间
一般来,我们在为应用程序的服务器选型时,要先对磁盘的IO性能进行基准测试,以便可以准确评估,磁盘性能是否可以满足应用程序的需求。
推荐使用性能工具测试fio,来来测试磁盘的IOPS、吞吐量以及响应时间等核⼼指标在基准测试时,⼀定要注意根据应⽤程序 I/O 的特点,来具体评估指标。需要测试出,不同 I/O ⼤⼩(⼀般是 512B ⾄ 1MB 中间的若⼲值)分别在随机读、顺序读、随机写、顺序写等各种场景下的性能情况。使用性能工具得到这些指标,可以作为后继分析应用程序性能的依据,一旦发⽣性能问题,你就可以把它们作为磁盘性能的极限值,进⽽评估磁盘 I/O 的使⽤情况
磁盘I/O观测
观测每块磁盘的使用情况
iostat 是最常⽤的磁盘I/O性能观测⼯具,它提供了每个磁盘的使⽤率、IOPS、吞吐量等各种常⻅的性能指标,当然,这些指标实际上来⾃ /proc/diskstats。
# -d -x表示显示所有磁盘I/O的指标 $ iostat -d -x 1 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 loop1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1234567第⼀列的 Device 表示磁盘设备的名字, 其他作用如下:
%util ,就是我们前⾯提到的磁盘I/O使⽤率;r/s+ w/s ,就是 IOPS;rkB/s+wkB/s ,就是吞吐量;r_await+w_await ,就是响应时间。在观测指标时,别忘了结合请求的⼤⼩( rareq-sz 和wareq-sz)⼀起分析。
从上面可以看出,从iostat中并不能直接得到磁盘饱和度。事实上,饱和度通常没有其他更简单的观测方法。不过,可以把观测到的,平均请求对了长度或者读写请求完成的等待时间,跟基准测试的结果(比如fio)进行对比,总和评估磁盘的饱和情况。
进程IO观测
除了每块磁盘的IO情况,每个进程的IO情况也是我们观测的重点。
但是iostat只提供磁盘整体的IO性能数据,并不能知道具体是哪些进程在进行磁盘读写。要观测进程的IO情况,需要使用pidstat和iotop
$ pidstat -d 1 # 每隔1s看一次进程的IO情况 13:39:51 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command 13:39:52 102 916 0.00 4.00 0.00 0 rsyslogd 123从pidstat的输出你能看到,它可以实时查看每个进程的I/O情况,包括下⾯这些内容。
⽤户ID(UID)和进程ID(PID)每秒读取的数据⼤⼩(kB_rd/s) ,单位是 KB。每秒发出的写请求数据⼤⼩(kB_wr/s) ,单位是 KB。每秒取消的写请求数据⼤⼩(kB_ccwr/s) ,单位是 KB。块I/O延迟(iodelay),包括等待同步块I/O和换⼊块I/O结束的时间,单位是时钟周期。除了可以用pidstat实时查看,也可以使用iotop根据IO大小对进行排序,然后找到I/O较⼤的那些进程:
$ iotop Total DISK READ : 0.00 B/s | Total DISK WRITE : 7.85 K/s Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 15055 be/3 root 0.00 B/s 7.85 K/s 0.00 % 0.00 % systemd-journald 12345前两行分别表示,进程的磁盘读写大小总数和磁盘真正的读写大小总数。因为缓存、缓冲区、IO合并等因素的影响,他们可能不相等剩下的部分,则是从各个⻆度来分别表示进程的I/O情况,包括线程ID、I/O优先级、每秒读磁盘的⼤⼩、每秒写磁盘的⼤⼩、换⼊和等待I/O的时钟百分⽐等。
0 留言