服务器端性能测试判断磁盘瓶颈的方法

文章目录

  以前做性能测试的时候,磁盘瓶颈总是判断的不太准确,这两天仔细研究了一下,记录一下研究的结果。

一、主流磁盘结构

现在主流的磁盘结构有两种:

(一)、不划分逻辑卷的结构

bash 复制代码
物理磁盘(sda ssd/hdd)
    ↓
分区1(sda1) → 文件系统 → 挂载 /boot
    ↓
分区2(sda2) → 文件系统 → 挂载 /
    ↓
分区3(sda3) → 文件系统 → 挂载 /data

  比如把 sda 划分了 3 个分区,其中 1 个叫 sda1,格式化成 ext4 或 xfs 格式(文件系统),挂载到了/boot 目录下。

  这种结构在磁盘空间不足的时候扩展起来不方便,适合小的系统。具体的原因是要实现存储扩展需要连续的存储空间,但是很难把两块硬盘从物理上前后连起来形成连续的存储空间。

(二)、划分逻辑卷的结构

bash 复制代码
物理磁盘 sda(SSD/HDD)
    ↓
物理分区 sda2 【标记为LVM物理卷 PV】
    ↓
卷组 VG(vg0):把一个或多个PV的空间打包成一个大资源池
    ↓
逻辑卷 LV(vg0‑root、vg0‑swap)
    ↓
格式化文件系统(xfs/ext4) → 挂载到 / 、swap

  一块物理磁盘PV可以进行分区(sda->sda1+sda2),多个分区可以组合成一个卷组(sda2->vg0,组成vg0卷组的只有一个 sda2,真实情况下可能还会有 hd1,hda2 等等),这个卷组就是一个大的资源池,在卷组下可以划分逻辑卷(vg0->vg0-root+vg0-swap),逻辑卷可以格式化后挂载到目标目录下。

  这种结构的卷组是可扩展的,因为有了 PV->VG->LV 的三层映射关系,当 LV 的空间满了,如果当前 VG 中还有剩余空间,可以直接申请扩充 PE(VG 系统中把 PV 组合后划分的最小存储单元),如果 VG 没有空间了,还可以给 VG 添加新的 PV,重新切割成 PE,再把 PE 分配给 VG。

二、常用命令

(一)、查看磁盘结构命令一 lsblk

bash 复制代码
[test@kylinv10 security]$ lsblk
NAME  					MAJ:MIN				RM			SIZE			R0			TYPE			MOUNTPOINT
sda						8:0					 0			100G			 0			disk
|-sda1					8:1					 0			1G			 	 0			part 			/boot
|-sda2					8:2				 	 0			99G				 0			part
  |-vg0-root			253:0				 0		 	91.1G			 0			lvm				/
  |-vg0-swap			253:1				 0     	 	7.9G			 0      	lvm				[swap]
  1. NAME磁盘名称,sda第一块物理磁盘;sda1/sda2磁盘分区;vg0‑root/vg0‑swapLVM 逻辑卷
  2. MAJ:MIN主 / 次设备号,内核识别硬件的编号
  3. RM是否可移动磁盘,0=本地硬盘,1=U盘/移动盘
  4. SIZE容量
  5. R0是否只读只读标志,0=可读写
  6. TYPE设备类型,disk物理磁盘,part普通分区,lvm 逻辑卷
  7. MOUNTPOINT挂载点,swap代表交换分区

(二)、查看磁盘结构命令二 pvdisplay

  这个命令需要 root 权限,一般用的比较少

bash 复制代码
[test@kylinv10 /]$ pvdisplay
--- Physical volume ---
PV Name						/dev/sdb
VG Name   					vg01
PV SIZE						31.43 TiB / not usable 4.00MiB
Allocatable					yes(but full)
PE Size						4.00MiB
Total PE						8240183
Free PE						0
Allocated PE				8240183
PV UUID           		Xoo**-**-**

--- Physical volume ---
PV Name						/dev/sdc
VG Name           			vg01
PV SIZE						31.43 TiB / not usable 4.00MiB
Allocatable					yes(but full)
PE Size						4.00MiB
Total PE					8240183
Free PE						0
Allocated PE				8240183
PV UUID           			Xoo**-**-**

  从上面可以看出来,我的机器上有两块大盘 /dev/sdb、/dev/sdc,都作为 PV 加入同一个卷组 vg01。两块盘大小完全一致:每块 31.43TiB,PE 默认 4MiB,两个 PV 的空间已经全部分配给了vg01,Free PE = 0,vg01 卷组已经没有可再分配给逻辑卷的空闲空间。

(三)、查看磁盘已经使用的容量 df -h

bash 复制代码
[test@kylinv10 /]$ df -h
文件系统						 		容量		已用		可用		已用%		挂载点
devtmpfs							3.9G		   0		3.9G		     0%		/dev
tmpfs								3.9G		 12K		3.9G			 1%		/dev/shm
tmpfs								3.9G		138M		3.8G			 4%		/run
tmpfs								3.9G		   0		3.9G			 0%		/sys/fs/cgroup
/dev/mapper/vg0-root	 			92G			9.3G		 82G			11%		/
tmpfs								3.9g		2.6K		3.9G			 1%		/tmp
/dev/sda1						 	1014M		529M		486M			53%		/boot
10.128.*.*/test_req					20G			1.2G		 19G			 6%  	/test_req
tmpfs								795M		   0		795M			 0%		/run/user/501
tmpfs								795M		   0		795M			 0%		/run/user/0
tmpfs								795M		   0		795M			 0%		/run/user/503

文件系统有三类,分别是 devtmpfs,tmpfs 和 带路径的存储盘。

第一类是devtmpfs内存存储,每次重启先清空后创建

  • 系统设备目录,存放磁盘、网卡、串口等硬件设备文件
  • 全部在内存,不消耗磁盘 ;容量约等于机器一半物理内存;0已用代表设备节点几乎不占存储。

第二类是tmpfs内存存储,重启清空

  • /dev/shm 共享内存;程序、Docker、数据库会用这块内存盘做共享内存通信。
  • /run:系统运行时目录,存 PID 文件、socket 套接字、服务临时状态。
  • /sys/fs/cgroup cgroup 相关挂载,内核用来限制进程 CPU、内存资源(docker 底层依赖 cgroup)。
  • /run/user/<uid>每个登录用户独立的 tmpfs
    • uid=0 是 root;501、503 是普通业务用户;
    • 用户登录时自动创建,用户退出登录自动销毁;内存存储,用于存放该用户的桌面、会话 socket 临时文件。

第三类是带路径的普通存储盘,存用户文件

  • /dev/sda1硬盘的第 1 个分区,挂载到/boot,存储内核引导文件
  • /dev/mapper/vg0-root第 0 个卷组的 root 卷,主要的存储空间
  • 10.128.*.*/test_req我挂载的共享存储 NAS 目录

(四)、查看虚拟卷别名对应的块设备名 ll /dev/mapper

bash 复制代码
[test@kylinv10 /]$ ll /dev/mapper
总用量 0
crw------- 1 root root		10,236 6月 19 00:41 control
lrwxrwxrwx 1 root root			7	6月 19 00:41 vg0-root -> ../dm-0
lrwxrwxrwx 1 root root 			7	6月 19 00:41 vg0-swap -> ../dm-1

dev/dm‑0(dm‑X):内核真实设备 ,内核只认识这个编号;

/dev/mapper/vg0‑root人为做的软链接,别名,给人看的,方便识别卷组‑逻辑卷名字

  Linux 内核访问块设备,根本不认识 vg0‑root 这种人类命名。

  内核识别设备唯一标识:主设备号:次设备号

  device‑mapper 的主设备号固定是 253:

  • 253:0/dev/dm‑0
  • 253:1/dev/dm‑1

  内核、驱动、io 调度、磁盘调度策略,全部操作的是 dm‑0/dm‑1

  软链接 /dev/mapper/vg0‑root 只是文件系统层面的符号链接,内核根本不知道这个名字存在

  把这个软链接删掉,系统照样跑,只是人类不方便识别设备。

(五)、查看当前系统 I/O 状况 iostat -x

bash 复制代码
[test@kylinv10 /]$ iostat
Linux 4.19.90-89.4.v2401.ky10.x86_64(kylinv10)		2026 年 08 月 14 日		(4CPU)
avg-cpu: %user	%nice		%system		%iowait		%steal		%idle
          0.17	 0.00			 0.15			 0.00		  0.00		99.68

Divce	r/s	rkB/s	rrqm/s	%rrqm	r_await	rareq-sz	w/s	wkB/s	wrqm/s	%wrqm	w_await	wareq-sz	d/s	dkB/s	drqm/s	%drqm	d_await	dareq-sz	aqu-ze	%util
dm-0	0.02	0.54	0	0	2.67	37.84	0.44 10.1	0	0	3.06	16.04	0	0	0	0	0	0	0	0.06
dm-1	0.01	0.53	0	0	2.67	37.84	0.44 10.1	0	0	3.06	16.04	0	0	0	0	0	0	0	0.06
sda	  0.03	0.53	0	0	2.67	37.84	0.44 10.1	0	0	3.06	16.04	0	0	0	0	0	0	0	0.06
序号 列名 英文 中文 备注
1 Device This column gives the device (or partition) name as listed in the /dev directory. 磁盘或分区名
2 sec/s(kB/s,MB/s) The number of sectors(kibibytes,mebibytes) read from,written to or discarded for the device per second. 每秒速度总和,包括读,写和忽略三种操作。单位可以是扇区数(1 个扇区 512 个 字节 Byte),KiB 和 MiB
3 r/s The number(after merges) of read requests completed per second for the device 每秒钟读磁盘的次数。 after merges 代表系统会把多个相邻的读请求合并成一次读磁盘的操作。
4 rsec/s(rkB/s,rMB/s) The number of sectors(kibibytes,mebibytes) read from the device per second. 每秒钟读取的数据量大小,单位可以是扇区数,KiB 和 MiB
5 rrqm/s The number of read requests merged per second that were queued to the device 每秒钟合并的读请求数量
6 %rrqm The percentage of read requests merged together before being sent to the device . 合并请求的百分比=被合并的请求数量/总的请求数量。比如 1 秒钟内来了 100 个请求,其中 30 个请求读的是连续的磁盘空间,那么这 30 个请求就会被合并成 1 个,有 29 个请求被合并了。发送给磁盘的请求数就是 70+1=71 个。%rrqm = 29/100 = 29%。 从 iostat 输出的内容看 %rrqm = (rrqm/s)/(rrqm/s)+(r/s) 这个比例越高,说明磁盘读请求被合并的比例高,效率就比较好,如果是 0 代表读的都是分散的区间,效率就不如读连续的区间高。
7 r_await The average time(in milliseconds) for read requests issued to the device to be served.This includes the time spent by the requests in queue and the time spend servicing them. 表示设备‌读请求的平均服务时间‌(单位为毫秒)。该数值包含了两个部分: + 请求在队列中等待的时间。 + 实际 servicing(处理)请求所花费的时间。
8 rareq-sz The average size(in kibibytes) of the read requests that were issued to the device. 读磁盘请求的平均大小,以 KiB 为计量单位 Windows 中的 1KB 有的时候表示 1000KB,有的时候表示 1024KB,Linux 中 一般 以 1024 作为换算比例1KiB=1024B
9 w/s The number(after merges) of write requests completed per second for the device 每秒钟写磁盘的次数。 after merges 代表系统会把多个相邻的写请求合并成一次读磁盘的操作。
10 wsec/s(wkB/s,wMB/s) The number of sectors(kibibytes,mebibytes) written to the device per second. 每秒钟写入磁盘的数据量大小,单位可以是扇区数,KB 和 MB
11 wrqm/s The number of write requests merged per second that were queued to the device 每秒钟合并的写请求数量
12 %wrqm The percentage of write requests merged together before being sent to the device. 合并请求的百分比=被合并的请求数量/总的请求数量。比如 1 秒钟内来了 100 个请求,其中 30 个请求读的是连续的磁盘空间,那么这 30 个请求就会被合并成 1 个,有 29 个请求被合并了。发送给磁盘的请求数就是 70+1=71 个。%rrqm = 29/100 = 29%。 这个比例越高,说明磁盘写请求被合并的比例高,效率就比较好,如果是 0 代表写的都是分散的区间,效率就不如读连续的区间高。
13 w_await The average time(in millseconds) for write requests issued to the devie to be served.This includes the time spent by the requests in queue and the time spent servcing them. 表示设备‌写请求的平均服务时间‌(单位为毫秒)。该数值包含了两个部分: + 请求在队列中等待的时间。 + 实际 servicing(处理)请求所花费的时间。
14 wareq-sz The average size(in kibibytes) of the write requests that issued to the device. 读磁盘请求的平均大小,以 KiB 为计量单位
15 d/s The number(after merges) of discard requests completed per second for the device 每秒钟合并的 discard 请求数。 discard 操作用于通知SSD哪些块已不再被文件系统使用,帮助SSD控制器提前完成垃圾回收,避免后续写入时才执行擦除操作,减少写放大,提升长期读写性能,同时延长闪存颗粒的使用寿命。
16 dsec/s(dkB/s,dMB/s) The number of sectors(kibibytes,mebibytes) discarded for the device per second. 每秒从设备上通过discard操作丢弃的数据量,单位是扇区数,kB 或者 mB。 反映系统当前SSD Trim、空间回收类操作的吞吐量,数值越高说明当前系统正在大量释放磁盘空闲块
17 drqm/s The number of discard requests merged per second that were queued to the device. 每秒合并的丢弃(Discard/TRIM)请求数量。 "合并"的概念‌当文件系统或应用程序发起多个相邻或连续的 Discard 请求时,Linux内核的 I/O 调度器会将这些小的、相邻的请求合并为一个更大的请求发送给底层块设备。
18 %drqm The percentage of discard requests merged together before being sent to the device. 合并请求的百分比=被合并的请求数量/总的请求数量。比如 1 秒钟内来了 100 个请求,其中 30 个请求 删除的是连续的磁盘空间,那么这 30 个请求就会被合并成 1 个,有 29 个请求被合并了。删除的请求数就是 70+1=71 个。%drqm = 29/100 = 29%。
19 d_await The average time(in millsecodes) for discard requests issued to the deivice to be served.This includes the time spent by the requests in queue and the time spent servcing them. 表示设备‌丢弃请求的平均服务时间‌(单位为毫秒)。该数值包含了两个部分: + 请求在队列中等待的时间。 + 实际 servicing(处理)请求所花费的时间。
20 dareq-sz The average size(in kibibytes) of the discard requests that were issued to the device. 丢弃请求的平均大小,以 KiB 为计量单位
21 aqu-sz The average queue length of the requests that were issued to the device.Note:In previous versions,this field was know as avgqu-sz. I/O 队列的平均长度。
22 %util Percentage of elapsed time during which I/O requests were issued to the device (bandwidth utilization for the device).Device saturation occurs when this value is close to 100% for devices serving requests serially.But for devices serving requests in parallel,such as RAID arrays and modern SSDS,this number does not reflect their performance limits. 设备在时间上的使用占用率。对于机械硬盘这种只能顺序写入的磁盘,这个值 100%代表磁盘性能已经达到了极限。但是对于可以并行写入的设备,比如 RAID 或者 SSD 盘 是支持并行写入的,只能代表一段时间内一直有内容在写入磁盘,并不代表达到了磁盘性能的上限

  一般我会用iostat -xt 3 2的形式,代表了每 3 秒钟打印一次 ,连续打印 2 次,每次把时间打印出来。

三、磁盘性能瓶颈的判断依据

  不能只看iostat -x 的 %util,因为这个参数仅代表了单位时间内,磁盘读,写,丢弃操作所占的时间比例,在 这个时间内,如果是支持并行操作的磁盘,还可以通过扩充并行度的方式提升性能。

  要结合 await(r_await,w_await,d_await) 和 aqu-sz 一起看,瓶颈是说磁盘处理不了更多的请求,过多的请求就会在队列里堆积,会出现 aqu-sz 持续增长的情形,由于排队的请求数量增多,会导致排队时间越来越长,进而致 await 持续增长。所以如果观察到 await 和 aque-sz 一起增长,就可以确定出现了磁盘 I/O 性能瓶颈。

  下图是一个出现I/O瓶颈的具体例子:

  上面的截图可以看到:

  1. cpu 的 %iowait 越来越高,cpu 等待 io 的时间越来越长
  2. sda 的 w_wait 越来越高,写操作处理时间越来越长
  3. sda 的 wareq-sz 越来越高,排队的请求越来越多
    说明 sda 这块盘出现了 I/O 瓶颈。
相关推荐
lisanmengmeng2 天前
搭建elk环境并接入frostmourne,实现监控报警效果(e二)
elk·监控·日志·日志监控
2651940511264807 天前
08-告警并发与多Master同步
go·监控
七夜zippoe8 天前
DolphinDB 产能分析实战:从产能规划到瓶颈优化的完整方法论
优化·规划·dolphindb·产能·瓶颈
lisanmengmeng8 天前
飞书 API使用
飞书·监控·日志·日志监控·监控及日志
三维地图技术社区8 天前
24小时降雨316.1毫米:城市内涝是怎么发生的?排水防涝体系与应急管理一次讲透
监控·图新说·城市内涝·排水防涝·应急管理·三维地下管网·应急预案三维可视化
2651940511264808 天前
07-告警引擎与状态机
go·监控
汤姆yu9 天前
基于python大数据的高校舆情监测系统的设计与实现
大数据·开发语言·python·分享·分析·舆情
科技风向标go12 天前
2026户外太阳能监控怎么选不踩坑?户外(格行AOV+黑光)、工程(海康大华)、生态(小米萤石)——三大派系技术路线全解析
大数据·人工智能·智能家居·监控·户外安防
两行法桐13 天前
SkyWalking 前端监控
监控