一、关于磁盘
磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘。
第一类,机械磁盘,也称为硬盘驱动器(Hard Disk Driver),通常缩写为 HDD。机械磁盘主要由盘片和读写磁头组成,数据就存储在盘片的环状磁道中。在读写数据前,需要移动读写磁头,定位到数据所在的磁道,然后才能访问数据。
显然,如果 I/O 请求刚好连续,那就不需要磁道寻址,自然可以获得最佳性能。这其实就是我们熟悉的,连续 I/O 的工作原理。与之相对应的,当然就是随机 I/O,它需要不停地移动磁头,来定位数据位置,所以读写速度就会比较慢。
第二类,固态磁盘(Solid State Disk),通常缩写为 SSD,由固态电子元器件组成。固态磁盘不需要磁道寻址,所以,不管是连续 I/O,还是随机 I/O 的性能,都比机械磁盘要好得多。
其实,无论机械磁盘,还是固态磁盘,相同磁盘的随机 I/O 都要比连续 I/O 慢很多,原因也很明显。
对机械磁盘来说,我们刚刚提到过的,由于随机 I/O 需要更多的磁头寻道和盘片旋转,它的性能自然要比连续 I/O 慢。
而对固态磁盘来说,虽然它的随机性能比机械硬盘好很多,但同样存在“先擦除再写入”的限制。随机读写会导致大量的垃圾回收,所以相对应的,随机 I/O 的性能比起连续 I/O 来,也还是差了很多。
此外,连续 I/O 还可以通过预读的方式,来减少 I/O 请求的次数,这也是其性能优异的一个原因。很多性能优化的方案,也都会从这个角度出发,来优化 I/O 性能
此外,机械磁盘和固态磁盘还分别有一个最小的读写单位:
机械磁盘的最小读写单位是扇区,一般大小为 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) 等。
不同的接口,往往分配不同的设备名称。比如, IDE 设备会分配一个 hd 前缀的设备名,SCSI 和 SATA 设备会分配一个 sd 前缀的设备名。如果是多块同类型的磁盘,就会按照 a、b、c 等的字母顺序来编号。
除了磁盘本身的分类外,当你把磁盘接入服务器后,按照不同的使用方式,又可以把它们划分为多种不同的架构。
最简单的,就是直接作为独立磁盘设备来使用。这些磁盘,往往还会根据需要,划分为不同的逻辑分区,每个分区再用数字编号。比如我们前面多次用到的 /dev/sda ,还可以分成两个分区 /dev/sda1 和 /dev/sda2。
另一个比较常用的架构,是把多块磁盘组合成一个逻辑磁盘,构成冗余独立磁盘阵列,也就是 RAID(Redundant Array of Independent Disks),从而可以提高数据访问的性能,并且增强数据存储的可靠性。
根据容量、性能和可靠性需求的不同,RAID 一般可以划分为多个级别,如 RAID0、RAID1、RAID5、RAID10 等。
RAID0 有最优的读写性能,但不提供数据冗余的功能。
而其他级别的 RAID,在提供数据冗余的基础上,对读写性能也有一定程度的优化。
最后一种架构,是把这些磁盘组合成一个网络存储集群,再通过 NFS、SMB、iSCSI 等网络存储协议,暴露给服务器使用。
其实在 Linux 中,磁盘实际上是作为一个块设备来管理的,也就是以块为单位读写数据,并且支持随机读写。
每个块设备都会被赋予两个设备号,分别是主、次设备号。主设备号用在驱动程序中,用来区分设备类型;而次设备号则是用来给多个同类设备编号。
二、工具安装
fio(Flexible I/O Tester)正是最常用的文件系统和磁盘 I/O 性能基准测试工具。
它提供了大量的可定制化选项,可以用来测试,裸盘或者文件系统在各种场景下的 I/O 性能,包括了不同块大小、不同 I/O 引擎以及是否使用缓存等场景。
# yum -y install epel-release
# yum -y install fio
三、测试场景
此次测试,被测试的磁盘挂载在 /opt 目录下
100随机读
# fio -filename=/opt/100_rand_read -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=10G -numjobs=50 -runtime=120 -group_reporting -name=rand_100read_4k
# tail -n 300 /var/log/messages
1. IOPS就是 I/O per second 的缩写,指的是发送给磁盘的读写请求数(注意这里是系统合并后发给磁盘的)
2. 每次请求的大小不是固定的,所以才会有 IOPS 和吞吐这些不同的指标
100随机写
# fio -filename=/opt/100_rand_write -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=10G -numjobs=50 -runtime=120 -group_reporting -name=rand_100read_4k
# tail -n 300 /var/log/messages
70随机读,30随机写
# fio -filename=/opt/70_rand_read_30_rand_write -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=10G -numjobs=50 -runtime=120 -group_reporting -name=randrw_70read_4k
# tail -n 300 /var/log/messages
30随机读 70随机写
# fio -filename=/opt/30_rand_read_70_rand_write -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=30 -ioengine=psync -bs=4k -size=10G -numjobs=50 -runtime=120 -group_reporting -name=randrw_30read_4k
# tail -n 300 /var/log/messages
四、参考
CentOS.x上磁盘性能测试工具fio的安装和使用
https://www.jianshu.com/p/f26543a38f09
fio压测工具和io队列深度理解和误区
http://blog.yufeng.info/archives/2104
fio – IO压力测试工具
https://younger.blog.csdn.net/article/details/71129541
fio安装使用方法
https://www.kclouder.cn/fio
fio模拟MySQL服务器IO压力脚本
http://blog.yufeng.info/archives/1497
fio使用详解
https://blog.csdn.net/m0_37972390/article/details/80019762
Fio Output Explained
https://tobert.github.io/post/2014-04-17-fio-output-explained.html
A script that runs fio test and genearates a simple result for each jobs
https://gist.github.com/sennajox/3667757
Linux 硬盘测试脚本
https://amefs.net/archives/1974.html
https://github.com/amefs/fio-bench
https://github.com/bootgo/tools/blob/master/fio.py