
背景
数据库系统是为了数据存储、管理、处理而发展起来的数据处理系统。随着信息化技术的飞速发展,越来越多的数据存储在数据库系统中,数据库的容量不断增长,一套核心计费数据库,每月的数据量可以达到30T。数据库系统对应用性能的影响越来越显著。
处理时间是衡量应用性能的一个重要指标,设备延迟在处理时间中占了很大的比重,延迟由硬件自身特性决定,除了更换硬件设备很难进行优化。
以下是Intel Xeon E5 CPU为基准的设备延迟信息表:
系统设备 | 真实延迟 | 缩放延迟 |
一个 CPU 指令 | 0.4 ns | 1 s |
CPU Level 1 缓存 | 0.9 ns | 2 s |
CPU Level 2 缓存 | 2.8 ns | 7 s |
CPU Level 3 缓存 | 28 ns (10 X L2) | 1 min |
DDR 内存 | 100 ns | 4 min |
Intel 傲腾 | <10 us | 7 hrs |
8GB HBA卡 | 50 us | 1.5 days |
NVMe 固态硬盘 | ~25 us | 17 hrs |
固态硬盘 | 50–150 μs | 1.5–4 days |
机械硬盘 | 1–10 ms | 1–9 months |
从上表中看,传统的机械硬盘的延迟是所以设备中最大的,磁盘的性能也就成为了影响数据库系统性能的最大因素。
因此通过I/O性能测试,可以直观的反应数据库系统的处理性能。
2

数据库系统的I/O请求,由数据库软件发起,通过数据库服务器上的接口卡,连接到存储网络交换机,存储网络交换机通过端口连接到存储设备的前端端口,存储设备内部通过控制器,对底层磁盘设备完成读写操作,存储前端端口将处理结果反馈给存储网络交换机,存储网络交换机将结果反馈给数据库服务器,最终数据库系统完成了I/O操作流程。
整个I/O处理路径,延迟随着经过设备数据量不断增加。
存储网络交换机和存储设备属于专业设备,日常由于网络和存储管理员维护,因此不在本次讨论范围。本文增针对数据库服务器内部的软件及硬件设备进行分析和讨论。
以下是本次测试服务器软件及硬件详细信息。
软件名称 | 版本 | 描述 |
操作系统 | Oracle Linux 7.5 | |
多路径软件 | device-mapper-multipath-0.4.9 | |
IO测试软件 | fio-3.7 | |
设备名称 | 型号 | 数量 |
服务器 | HP ProLiant DL580 Gen9 | 2 |
CPU | Intel(R) Xeon(R) CPU E7-4820 v3 | 4 |
内存 | DDR4 2133MHz 32GB | 16 |
HBA卡 | HP 8Gb Dual channel PCI-e 2.0 FC HBA | 2 |
磁盘 | 500GB | 3 |
存储设备 | 磁盘类型 | 数量 |
HP 3PAR StoreServ 20800 | Seagate 600G 15K FC | 50 |
没有 DM-Multipath软件的情况下,从服务器节点到存储控制器的所有路径都将被系统视为独立的设备,即使连接相同服务器节点到相同存储控制器的 I/O 路径也不例外。DM-Multipath 提供了逻辑管理 I/O 路径的方法,即在基础设备的顶部生成单一多路径设备。通过多路径的方式,可以有效避免I/O路径的单点故障,保护数据库的I/O请求顺利执行。

下面简单描述存储LUN映射到数据库服务器,并最终绑定为数据库可用的块设备。
1) 检查数据库服务器的HBA卡,当前服务器有2块双口HBA卡,每块卡只连接一根光纤线,黄色及蓝色标记的为连接光纤的HBA卡端口。
[root@dzqddb1 disk]# lspci | grep -i hba
c1:00.0 Fibre Channel: QLogic Corp. ISP2532-based 8Gb Fibre Channel to PCI Express HBA (rev 02)
c1:00.1 Fibre Channel: QLogic Corp. ISP2532-based 8Gb Fibre Channel to PCI Express HBA (rev 02)
c4:00.0 Fibre Channel: QLogic Corp. ISP2532-based 8Gb Fibre Channel to PCI Express HBA (rev 02)
c4:00.1 Fibre Channel: QLogic Corp. ISP2532-based 8Gb Fibre Channel to PCI Express HBA (rev 02)
服务器HBA端口编号
[root@dzqddb1 ~]# cd sys/class/fc_host
[root@dzqddb1 fc_host]# ll
host1 -> ../../devices/pci0000:c0/0000:c0:02.0/0000:c4:00.0/host1/fc_host/host1
host2 -> ../../devices/pci0000:c0/0000:c0:02.0/0000:c4:00.1/host2/fc_host/host2
host3 -> ../../devices/pci0000:c0/0000:c0:03.0/0000:c1:00.0/host3/fc_host/host3
host4 -> ../../devices/pci0000:c0/0000:c0:03.0/0000:c1:00.1/host4/fc_host/host4
[root@dzqddb1 fc_host]# cat sys/class/fc_host/host1/port_name
0x51402ec001bf90b8
[root@dzqddb1 fc_host]# cat sys/class/fc_host/host2/port_name
0x51402ec001bf90ba
[root@dzqddb1 fc_host]# cat sys/class/fc_host/host3/port_name
0x51402ec001bf8c68
[root@dzqddb1 fc_host]# cat sys/class/fc_host/host4/port_name
0x51402ec001bf8c6a
存储前端端口编号
[root@dzqddb1 ~]# cd sys/class/fc_remote_ports
[root@dzqddb1 fc_remote_ports]# ll
rport-1:0-0 -> ../../devices/pci0000:c0/0000:c0:02.0/0000:c4:00.0/host1/rport-1:0-0/fc_remote_ports/rport-1:0-0
rport-1:0-1 -> ../../devices/pci0000:c0/0000:c0:02.0/0000:c4:00.0/host1/rport-1:0-1/fc_remote_ports/rport-1:0-1
rport-3:0-0 -> ../../devices/pci0000:c0/0000:c0:03.0/0000:c1:00.0/host3/rport-3:0-0/fc_remote_ports/rport-3:0-0
rport-3:0-1 -> ../../devices/pci0000:c0/0000:c0:03.0/0000:c1:00.0/host3/rport-3:0-1/fc_remote_ports/rport-3:0-1
[root@dzqddb1 ~]# cd sys/class/fc_remote_ports
[root@dzqddb1 fc_remote_ports]# cat rport-1:0-0/port_name
0x21420002ac01b3a1
[root@dzqddb1 fc_remote_ports]# cat rport-1:0-1/port_name
0x20420002ac01b3a1
[root@dzqddb1 fc_remote_ports]# cat rport-3:0-0/port_name
0x21410002ac01b3a1
[root@dzqddb1 fc_remote_ports]# cat rport-3:0-1/port_name
0x20410002ac01b3a1
2) 每一块SCSI磁盘,都有一个唯一的编号(WWID),选择一块500GB的磁盘,查看磁盘的WWID。
[root@dzqddb1 ~]# usr/lib/udev/scsi_id -gud dev/sdak
360002ac0000000000000035a0001b3a1
3) 通过磁盘设备by-id目录验证sdak磁盘的设备编号,与上面查询的结果一致。
[root@dzqddb1 ~]# ls -la dev/disk/by-id | grep sdak
lrwxrwxrwx 1 root root 10 Aug 31 11:49 scsi-360002ac0000000000000035a0001b3a1 -> ../../sdak
lrwxrwxrwx 1 root root 10 Aug 31 11:49 wwn-0x60002ac0000000000000035a0001b3a1 -> ../../sdak
4) 通过磁盘设备by-path目录,获取该磁盘设备的存储lun编号,通过存储lun编号,可以获取该存储lun映射到服务器的所有磁盘设备名称。从查询结果可以看出,sdak对应的存储lun编号为lun-12,lun-12在服务器上一共生成了4个映射的磁盘设备,对应的HBA卡端口为c1:00.0和c4:00.0。设备的路径编号与存储前端端口的编号一致,表面该磁盘设备是由对应的前端端口映射而来的。
[root@dzqddb1 ~]# ls -la dev/disk/by-path | grep sdak
lrwxrwxrwx 1 root root 10 Aug 31 11:49 pci-0000:c1:00.0-fc-0x20410002ac01b3a1-lun-12 -> ../../sdak
[root@dzqddb1 ~]# cd sys/class/fc_remote_ports
[root@dzqddb1 fc_remote_ports]# cat rport-1:0-0/port_name
0x21420002ac01b3a1
[root@dzqddb1 fc_remote_ports]# cat rport-1:0-1/port_name
0x20420002ac01b3a1
[root@dzqddb1 fc_remote_ports]# cat rport-3:0-0/port_name
0x21410002ac01b3a1
[root@dzqddb1 fc_remote_ports]# cat rport-3:0-1/port_name
0x20410002ac01b3a1
[root@dzqddb1 ~]# ls -la dev/disk/by-path | grep lun-12
lrwxrwxrwx 1 root root 10 Aug 31 11:49 pci-0000:c1:00.0-fc-0x20410002ac01b3a1-lun-12 -> ../../sdak
lrwxrwxrwx 1 root root 9 Aug 31 11:49 pci-0000:c1:00.0-fc-0x21410002ac01b3a1-lun-12 -> ../../sdq
lrwxrwxrwx 1 root root 10 Aug 31 11:49 pci-0000:c4:00.0-fc-0x20420002ac01b3a1-lun-12 -> ../../sdal
lrwxrwxrwx 1 root root 9 Aug 31 11:49 pci-0000:c4:00.0-fc-0x21420002ac01b3a1-lun-12 -> ../../sdr
5) 通过多路径命令查看,与前面查询的磁盘路径信息一致。
[root@dzqddb1 device]# multipath -l
asmdatadisk01 (360002ac0000000000000035a0001b3a1) dm-10 3PARdata,VV
size=500G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='round-robin 0' prio=0 status=active
|- 1:0:0:12 sdr 65:16 active undef unknown
|- 3:0:0:12 sdq 65:0 active undef unknown
|- 1:0:1:12 sdal 66:80 active undef unknown
`- 3:0:1:12 sdak 66:64 active undef unknown
6) Linux中设备管理是通过udev服务进行发现和绑定,通过udevadm命令进行上述信息的核对,HBA卡信息,磁盘的by-id、by-path的映射关系均与前面分析的结果一致。
[root@dzqddb1 ~]# udevadm info --query=all --name=/dev/sdak
P: /devices/pci0000:c0/0000:c0:03.0/0000:c1:00.0/host3/rport-3:0-1/target3:0:1/3:0:1:12/block/sdak
N: sdak
S: disk/by-id/scsi-360002ac0000000000000035a0001b3a1
S: disk/by-id/wwn-0x60002ac0000000000000035a0001b3a1
S: disk/by-path/pci-0000:c1:00.0-fc-0x20410002ac01b3a1-lun-12
E: DEVLINKS=/dev/disk/by-id/scsi-360002ac0000000000000035a0001b3a1
/dev/disk/by-id/wwn-0x60002ac0000000000000035a0001b3a1
/dev/disk/by-path/pci-0000:c1:00.0-fc-0x20410002ac01b3a1-lun-12
E: DEVNAME=/dev/sdak
E: DEVPATH=/devices/pci0000:c0/0000:c0:03.0/0000:c1:00.0/host3/rport-3:0-1/target3:0:1/3:0:1:12/block/sdak
E: ID_BUS=scsi
E: ID_FS_TYPE=mpath_member
E: ID_MODEL=VV
E: ID_MODEL_ENC=VV\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
E: ID_PATH=pci-0000:c1:00.0-fc-0x20410002ac01b3a1-lun-12
E: ID_PATH_TAG=pci-0000_c1_00_0-fc-0x20410002ac01b3a1-lun-12
E: ID_SCSI=1
E: ID_SCSI_SERIAL=SGH630W7SV
E: ID_SERIAL=360002ac0000000000000035a0001b3a1
E: ID_SERIAL_SHORT=60002ac0000000000000035a0001b3a1
E: ID_TARGET_PORT=1
E: ID_TYPE=disk
E: ID_VENDOR=3PARdata
E: ID_VENDOR_ENC=3PARdata
E: ID_WWN=0x60002ac000000000
E: ID_WWN_VENDOR_EXTENSION=0x0000035a0001b3a1
E: ID_WWN_WITH_EXTENSION=0x60002ac0000000000000035a0001b3a1
存储设备的性能由使用的存储介质决定。目前主流存储使用的存储设备主要为:机械硬盘(HDD),固态硬盘(SSD)以及最新的NVMe SSD。
在实际的业务系统中,IO请求是混合的,既有索引范围扫描的随机读,也有全表查询的顺序读,因此根据根据业务特性以及存储设备的特性,对磁盘设备的性能指标进行提炼,主要包含如下指标:
Ø IOPS
IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求数量为单位。一般设备厂家选择4K IO块大小进行IOPS测试,典型的ORACLE数据库环境中IO块大小为8K。在数据库OLTP应用场景,通常以IOPS衡量系统性能。
Ø 带宽(MBPS)
带宽即每秒钟可以处理的数据量,常以KB/S或MB/s或GB/s为单位,表示为KBPS/MBPS/GBPS,用于衡量存储系统的吞吐量(Throughput)。在数据库OLAP(Online Analytical Processing)业务、媒资业务、视频监控业务等应用场景,通常以带宽衡量系统性能。
Ø 延迟(latency)
延迟又称为服务时间或响应时间,指磁盘读或写操作执行的时间,包括寻道,旋转时延,和数据传输等时间。其大小一般和磁盘性能有关。机械硬盘的延迟时间大约在10ms左右,固态硬盘在50us左右。
Ø 队列深度(Queue Depth)
队列深度指同时等待在端口队列中进行服务的I/O请求数。SAS和SATA可以分别处理254和32的队列深度,NVMe SSD能够处理高达65000的队列深度。如果I/O请求的数量超过最大的队列深度,则该请求将在一段时间后重新尝试。
我们选取3款典型的产品,来看看磁盘设备的主要性能指标:
机械硬盘(HDD) | 固态硬盘(SSD) | NVMe SSD | |
产品 | 希捷 ST4000DM006 | INTEL SSD 545S | Intel SSD DC P4600 |
接口类型 | SATA 6Gb/s | 6 Gb/s SATA接口 | PCIe NVMe 3.1 x4 |
容量 | 4TB | 1.00 TB | 4.00 TB |
顺序读 | 220MB/s | 550 MB/s | 3200 MB/s |
随机读 | 76 | 85000 | 617500 |
顺序写 | 500 MB/s | 1900 MB/s | |
随机写 | 75000 | 225000 | |
读延迟 | 9 ms | 50 µs | 82 µs |
写延迟 | 9 ms | 50 µs | 30 µs |
价格 | 700¥ | 1500¥ | 19000¥ |
注:机械硬盘中标注为灰色部分的值非官方数据,数据是7200转硬盘经验值。产品价格来自官方建议价格。
下面是主流机械硬盘的响应时间与IOPS值。
7200转 | 10000 转 | 15000 转 | |
平均寻道时间 | 9 ms | 6 ms | 4 ms |
最大IOPS | 76 | 111 | 166 |
从上面的信息可以看到,固态硬盘的IOPS要远高于机械硬盘,在1000倍以上,尤其是NVMe SSD,IOPS较传统的机械硬盘,高10000倍左右,带宽也要高10倍左右。因此在使用固态硬盘设备以后,存储设备的性能会有非常大的提升。
传统的机械硬盘,通过使用大量的磁盘和缓存技术,可以获得较高的带宽,和比较高的IOPS,但是永远无法获得固态硬盘设备的低延迟。因此,目前主流存储正在朝固态硬盘设备方向发展。
fio 是目前非常流行的I/O系统测试工具。作者Jens Axboe是Linux I/O子系统的维护者。通过fio,我们可以构造不同的测试场景,对磁盘设备的IOPS、带宽、延迟、队列深度等指标进行分析。
注意:fio提供写测试功能,操作不当会造成磁盘数据丢失,测试写功能,建议使用未使用的磁盘,或者使用--readonly选项,禁用写操作。
fio的参数涵盖了几乎整个Linux I/O系统的配置,因此只列举了一些常用参数:
参数 | 描述 | 备注 |
name | 测试作业名称 | |
filename | I/O测试文件名,支持文件系统或者裸设备 | 多个文件: filename=/dev/sda:/dev/sdb |
blocksize | 单次I/O块大小,单位为字节 | 默认4K |
readwrite | 读写类型 | Read:顺序读 Write:顺序写 Randread:随机读 Randwrite:随机写 rw,readwrite:读写混合 |
ioengine | IO测试引擎 | Linux平台采用libaio模式 |
direct | 测试过程是否绕过系统页面缓存,1表示直接I/O,测试结果更真实 | 默认为:0 |
iodepth | 使用aio时,同时发出I/O请求数的上限值 | |
numjobs | 测试作业进程数 | |
runtime | 测试时长 | |
time_based | 在runtime指定的时间还没到时文件就被读写完成,将继续重复知道runtime时间结束。 | |
group_reporting | 汇总每个进程的测试信息 |
测试磁盘设备信息如下:
[root@dzqddb1 device]# multipath -l
asmdatadisk01 (360002ac0000000000000035a0001b3a1) dm-10 3PARdata,VV
size=500G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='round-robin 0' prio=0 status=active
|- 1:0:0:12 sdr 65:16 active undef unknown
|- 3:0:0:12 sdq 65:0 active undef unknown
|- 1:0:1:12 sdal 66:80 active undef unknown
`- 3:0:1:12 sdak 66:64 active undef unknown
1) 测试单块物理磁盘IOPS(本次测试用于解读fio测试结果)
通过简单测试,对fio测试结果进行解读
[root@dzqddb1 ~]# fio --name=sdak-4k-read --filename=/dev/sdak --blocksize=4k --readwrite=read --iodepth=1 --direct=1 --ioengine=libaio --group_reporting --runtime=60 --time_based
sdak-4k-read: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
fio-3.7
Starting 1 process
Jobs: 1 (f=1): [R(1)][100.0%][r=31.3MiB/s,w=0KiB/s][r=8017,w=0 IOPS][eta 00m:00s]
作业状态显示
sdak-4k-read: (groupid=0, jobs=1): err= 0: pid=5308: Tue Sep 11 15:42:05 2018
read: IOPS=8117, BW=31.7MiB/s (33.2MB/s)(1903MiB/60001msec) 本次测试IOPS:8117,带宽 31.7MB/s,IO操作数据量1903MB,测试时长60s(60001ms)
slat (usec): min=13, max=640, avg=19.64, stdev= 7.10
clat (usec): min=3, max=23399, avg=102.07, stdev=141.66
lat (usec): min=98, max=23418, avg=121.92, stdev=141.92 平均延迟
clat percentiles (usec):
| 1.00th=[ 88], 5.00th=[ 89], 10.00th=[ 90], 20.00th=[ 91],
| 30.00th=[ 92], 40.00th=[ 93], 50.00th=[ 94], 60.00th=[ 96],
| 70.00th=[ 98], 80.00th=[ 102], 90.00th=[ 105], 95.00th=[ 110],
| 99.00th=[ 221], 99.50th=[ 343], 99.90th=[ 668], 99.95th=[ 3458],
| 99.99th=[ 6390]
bw ( KiB/s): min=27096, max=34848, per=100.00%, avg=32478.84, stdev=1682.34, samples=119 带宽的最小值、最大值,以及平均值
iops : min= 6774, max= 8714, avg=8119.68, stdev=420.55, samples=119 IOPS的最小值、最大值,以及平均值
lat (usec) : 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01%, 100=74.62% 延迟的主要分布时间范围
lat (usec) : 250=24.47%, 500=0.60%, 750=0.21%, 1000=0.01%
lat (msec) : 2=0.01%, 4=0.04%, 10=0.03%, 20=0.01%, 50=0.01%
cpu : usr=3.45%, sys=25.28%, ctx=487292, majf=0, minf=15
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% IO队列深度,本次测试使用队列数为1
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=487083,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=31.7MiB/s (33.2MB/s), 31.7MiB/s-31.7MiB/s (33.2MB/s-33.2MB/s), io=1903MiB (1995MB), run=60001-60001msec
Disk stats (read/write): 磁盘统计信息,多路径设备会有多块磁盘的统计信息
sdak: ios=485275/18, merge=0/0, ticks=49366/0, in_queue=48943, util=81.72%
2) 测试队列深度对单块磁盘IOPS的影响
队列深度指同时等待在队列中进行服务的I/O请求数。调整--iodepth参数,通过模拟不同的队列深度,查看在不同队列深度下,磁盘可以达到的IOPS。理论上,随着队列深度的增加,磁盘接受到的I/O请求会不断增加,当达到磁盘的最大值时,后续的I/O请求会进入等待状态。
[root@dzqddb1 ~]# fio --name=sdak-4k-read --filename=/dev/sdak --blocksize=4k --readwrite=read --iodepth=1 --direct=1 --ioengine=libaio --group_reporting

从测试数据结果来看,当队列深度达到16时,单块硬盘的IOPS达到最大值,后续随着队列深度的不断增加,IOPS基本稳定在这个值附近。查看测试磁盘的队列深度属性为32,与测试结果相匹配。
[root@dzqddb1 ~]# lsscsi -l | grep -A 1 sdak
[3:0:1:12] disk 3PARdata VV 3224 /dev/sdak
state=running queue_depth=32 scsi_level=7 type=0 device_blocked=0 timeout=30
3) 测试作业进程数对IOPS的影响
单个进程的处理能力有限的,为了提高处理能力,最常用的方法就是增加处理的进程数。在队列深度的测试中,我们使用了单个进程进行IOPS测试,磁盘的队列深度为32。在队列32的基础上,调整--numjobs参数,加大测试进程数。
[root@dzqddb1 ~]# fio --name=sdak-4k-read-job --filename=/dev/sdak --blocksize=4k --readwrite=read --iodepth=32 --numjobs=1 --direct=1 --ioengine=libaio --group_reporting --runtime=60 --time_based

从测试数据结果来看,随着作业进程数的增加,磁盘的IOPS会逐渐增加,当进程数达到16以后,IOPS达到稳定值。此时磁盘的IOP为169000,该值是单块磁盘可以达到的最大IOPS。
4) 测试单块磁盘的带宽
带宽是每秒钟可以处理的数据量。单路径磁盘是通过单块HBA映射生成的设备。以/dev/sdak为例,该磁盘是由于host3接口生成的设备:
P: devices/pci0000:c0/0000:c0:03.0/0000:c1:00.0/host3/rport-3:0-1/target3:0:1/3:0:1:12/block/sdak
调整--blocksize参数,测试磁盘可以达到的最大带宽。
[root@dzqddb1 ~]# fio --name=sdak-4k-read-job --filename=/dev/sdak --blocksize=4k --readwrite=read --iodepth=32 --numjobs=32 --direct=1 --ioengine=libaio --group_reporting --runtime=60 --time_based

从上图结果看,单块磁盘可以达到的最大带宽约在780M。8Gb HBA卡的编码为8b/10b,也就是10bit的数字,有效数据为8bit,因此8Gb HBA的理论最大带宽为800MB/s ((8Gb 8) * (8b 10b) = 800MB)。因此单块磁盘的带宽在合理范围内。
5) 测试多块磁盘的IOPS
选择2块磁盘进行IOPS测试,IOPS测试结果为IOPS=252k。
[root@dzqddb1 ~]# fio --name=sdak-4k-read-job --filename=/dev/sdj:/dev/sdac --blocksize=4k --readwrite=read --iodepth=32 --numjobs=128 --direct=1 --ioengine=libaio --group_reporting --runtime=120 --time_based
sdak-4k-read-job: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=32
Starting 128 processes
Jobs: 128 (f=256): [R(128)][100.0%][r=1008MiB/s,w=0KiB/s][r=258k,w=0 IOPS][eta 00m:00s]
sdak-4k-read-job: (groupid=0, jobs=128): err= 0: pid=61717: Tue Sep 11 17:10:32 2018
read: IOPS=252k, BW=985MiB/s (1033MB/s)(115GiB/120012msec)
Disk stats (read/write):
sdj: ios=1062075/12, merge=13550558/0, ticks=14206287/129, in_queue=15581878, util=100.00%
sdac: ios=985035/0, merge=13664689/0, ticks=14278594/0, in_queue=15803299, util=100.00%
选择3块磁盘进行IOPS测试,IOPS测试结果为IOPS=302k。
[root@dzqddb1 ~]# fio --name=sdak-4k-read-job --filename=/dev/sdj:/dev/sdac:/dev/sdao --blocksize=4k --readwrite=read --iodepth=32 --numjobs=128 --direct=1 --ioengine=libaio --group_reporting --runtime=120 --time_based
sdak-4k-read-job: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=32
Starting 128 processes
Jobs: 128 (f=384): [R(128)][100.0%][r=1180MiB/s,w=0KiB/s][r=302k,w=0 IOPS][eta 00m:00s]
sdak-4k-read-job: (groupid=0, jobs=128): err= 0: pid=63523: Tue Sep 11 17:14:15 2018
read: IOPS=302k, BW=1178MiB/s (1235MB/s)(138GiB/120018msec)
Disk stats (read/write):
sdj: ios=1945755/16, merge=9600345/0, ticks=14133990/102, in_queue=14967417, util=100.00%
sdac: ios=1133006/1, merge=10462100/0, ticks=14249509/17, in_queue=15304085, util=100.00%
sdao: ios=641475/12, merge=11021044/0, ticks=14476535/276, in_queue=15889274, util=100.00%
通过上面的多块磁盘测试,表明磁盘数量增加后,IOPS会有提升。
6) 测试多路径磁盘的IOPS
选择多路径设备/dev/dm-10,作为fio测试的对象。从测试结果看,多路径设备的每条路径,I/O数量比较均衡。但由于多路径聚合以后的设备,在进行设备访问时,会对每条路径进行数据的分发,导致多路径设备的IOPS会低于多路径设备中的单块磁盘。
[root@dzqddb1 ~]# fio --name=sdak-4k-read-job --filename=/dev/dm-10 --blocksize=4k --readwrite=read --iodepth=32 --numjobs=64 --direct=1 --ioengine=libaio --group_reporting --runtime=60 --time_based
sdak-4k-read-job: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=32
Starting 64 processes
Jobs: 64 (f=64): [R(64)][100.0%][r=256MiB/s,w=0KiB/s][r=65.4k,w=0 IOPS][eta 00m:00s]
sdak-4k-read-job: (groupid=0, jobs=64): err= 0: pid=34846: Tue Sep 11 16:30:19 2018
read: IOPS=64.4k, BW=251MiB/s (264MB/s)(14.7GiB/60004msec)
Disk stats (read/write):
dm-10: ios=3856928/20, merge=514/0, ticks=9159208/35, in_queue=9235850, util=100.00%, aggrios=965317/5, aggrmerge=0/0, aggrticks=1209399/4, aggrin_queue=1208679, aggrutil=98.98%
sdr: ios=965317/6, merge=0/0, ticks=1190081/3, in_queue=1189388, util=98.73%
sdq: ios=965321/1, merge=0/0, ticks=1275951/0, in_queue=1275175, util=98.94%
sdal: ios=965316/7, merge=0/0, ticks=1133715/13, in_queue=1133009, util=98.76%
sdak: ios=965317/6, merge=0/0, ticks=1237849/3, in_queue=1237147, util=98.98%
7) 测试多路径磁盘的带宽
选择多路径设备/dev/dm-10,作为fio测试的对象。从测试结果看,多路径设备的每条路径,I/O数量比较均衡,多路径磁盘的带宽为1569MiB/s。多路径磁盘会通过两块HBA卡设备进行数据访问,因此总带宽为2块8Gb HBA的带宽,与1569MiB/s测试结果一致。
[root@dzqddb1 ~]# fio --name=sdak-4k-read-job --filename=/dev/dm-10 --blocksize=1m --readwrite=read --iodepth=32 --numjobs=32 --direct=1 --ioengine=libaio --group_reporting --runtime=60 --time_based
sdak-4k-read-job: (g=0): rw=read, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=libaio, iodepth=32
Starting 32 processes
Jobs: 32 (f=32): [R(32)][100.0%][r=1569MiB/s,w=0KiB/s][r=1568,w=0 IOPS][eta 00m:00s]
sdak-4k-read-job: (groupid=0, jobs=32): err= 0: pid=46748: Tue Sep 11 16:47:15 2018
read: IOPS=1568, BW=1568MiB/s (1645MB/s)(92.1GiB/60111msec)
Run status group 0 (all jobs):
READ: bw=1568MiB/s (1645MB/s), 1568MiB/s-1568MiB/s (1645MB/s-1645MB/s), io=92.1GiB (98.9GB), run=60111-60111msec
Disk stats (read/write):
dm-10: ios=93924/16, merge=128/0, ticks=8764644/563, in_queue=8774363, util=99.96%, aggrios=23549/4, aggrmerge=0/0, aggrticks=2196561/140, aggrin_queue=2196122, aggrutil=99.82%
sdr: ios=23550/3, merge=0/0, ticks=3882544/224, in_queue=3882254, util=99.82%
sdq: ios=23550/4, merge=0/0, ticks=399542/8, in_queue=398977, util=99.43%
sdal: ios=23548/5, merge=0/0, ticks=442245/9, in_queue=441623, util=99.54%
sdak: ios=23550/4, merge=0/0, ticks=4061914/320, in_queue=4061636, util=99.81%
硬盘从存储设备到映射到服务器生成磁盘设备文件,经过了一条复杂的链路。通过对多路径软件链路聚合过程的分析,我们了解了设备从存储LUN到多路径设备生成的流程。了解如何查看设备命令的方式和规则。
I/O是很多系统中的一个重要指标,尤其在数据库系统中。因此我们通过 fio 对磁盘的I/O进行模拟测试,通过测试对IOPS、带宽、队列深度等指标进行分析。我们得到了一些成果性的结论:
1) 通过调整队列深度可以提高磁盘的I/O性能。
2) 增加处理进程的数量可以提高磁盘的I/O性能。
3) 通过多路径可以提高存储磁盘的带宽。
4) 多路径在各链路间对I/O请求进行分发,会导致IOPS会有一定的损耗。
5) 通过增加磁盘设备的数量,会提升系统的IOPS。
有了这些基础知识和测试方法,我们就可以选择合理的存储设备、存储网络设备,规划和设计更加合理的数据库系统。
当然,I/O系统是一个复杂的系统,想要更加深入的了解,可以参考 fio 的 man 手册,或者通过更加底层的跟踪手段(strace/blkstrace)进行深层次的分析。


| 北京 | 上海 | 广州 | 成都 |
4008-906-960





