磁盘
磁盘文件
在分析和磁盘相关的问题时,通常是将其和文件系统同时考虑的,下面不再区分。和磁盘
- 磁盘
I/O 利用率:是指磁盘处理I/O 的时间百分比; - 磁盘吞吐量:是指每秒的
I/O 请求大小,单位为KB; I/O 响应时间,是指I/O 请求从发出到收到响应的间隔,包含在队列中的等待时间和实际处理时间;- IOPS(Input/Output Per Second
) :每秒的I/O 请求数; I/O 等待队列大小,指的是平均I/O 队列长度,队列长度越短越好;
如何判断磁盘的指标出现了异常?
-
当磁盘
I/O 利用率长时间超过80% ,或者响应时间过大(对于SSD ,从0.0x 毫秒到1.x 毫秒不等,机械磁盘一般为5ms~10ms ) ,通常意味着磁盘I/O 存在性能瓶颈; -
如果
%util 很大,而rkB/s 和wkB/s 很小,一般是因为存在较多的磁盘随机读写,最好把随机读写优化成顺序读写, (可以通过strace 或者blktrace 观察I/O 是否连续判断是否是顺序的读写行为,随机读写应可关注IOPS 指标,顺序读写可关注吞吐量指标) ; -
如果
avgqu-sz 比较大,说明有很多I/O 请求在队列中等待。一般来说,如果单块磁盘的队列长度持续超过2 ,一般认为该磁盘存在I/O 性能问题。
注意此处的寻道不能简单地理解成磁盘磁头旋转到指定位置,因为后备块设备可能是
磁盘的性能评价
SAN(
每秒
- Toatal IOPS,混合读写和顺序随机
IO 负载情况下的磁盘IOPS ,这个与实际IO 情况最为相符,大多数应用关注此指标。 - Random Read IOPS,
100% 随机读负载情况下的IOPS 。 - Random Write IOPS,
100% 随机写负载情况下的IOPS 。 - Sequential Read IOPS,
100% 顺序读负载情况下的IOPS 。 - Sequential Write IOPS,
100% 顺序写负载情况下的IOPS 。
IOPS 计算公式
对于磁盘来说一个完整的
在我们看硬盘厂商的宣传单的时候我们经常能看到
第一个寻址时间,考虑到被读写的数据可能在磁盘的任意一个磁道,既有可能在磁盘的最内圈
第二个旋转延时,和寻址一样,当磁头定位到磁道之后有可能正好在要读写扇区之上,这时候是不需要额外额延时就可以立刻读写到数据,但是最坏的情况确实要磁盘旋转整整一圈之后磁头才能读取到数据,所以这里我们也考虑的是平均旋转延时,对于
第三个传送时间,磁盘参数提供我们的最大的传输速度,当然要达到这种速度是很有难度的,但是这个速度却是磁盘纯读写磁盘的速度,因此只要给定了单次
现在我们就可以得出这样的计算单次
IO Time = Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate
于是我们可以这样计算出
IOPS = 1/IO Time = 1/(Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate)
对于给定不同的
4K (1/7.1 ms = 140 IOPS) 5ms + (60sec/15000RPM/2) + 4K/40MB = 5 + 2 + 0.1 = 7.1 8k (1/7.2 ms = 139 IOPS) 5ms + (60sec/15000RPM/2) + 8K/40MB = 5 + 2 + 0.2 = 7.2 16K (1/7.4 ms = 135 IOPS) 5ms + (60sec/15000RPM/2) + 16K/40MB = 5 + 2 + 0.4 = 7.4 32K (1/7.8 ms = 128 IOPS) 5ms + (60sec/15000RPM/2) + 32K/40MB = 5 + 2 + 0.8 = 7.8 64K (1/8.6 ms = 116 IOPS) 5ms + (60sec/15000RPM/2) + 64K/40MB = 5 + 2 + 1.6 = 8.6
从上面的数据可以看出,当单次
上面我们的数据都是在一个比较理想的假设下得出来的,这里的理想的情况就是磁盘要花费平均大小的寻址时间和平均的旋转延时,这个假设其实是比较符合我们实际情况中的随机读写,在随机读写中,每次
4K (1/0.1 ms = 10000 IOPS) 0ms + 0ms + 4K/40MB = 0.1 8k (1/0.2 ms = 5000 IOPS) 0ms + 0ms + 8K/40MB = 0.2 16K (1/0.4 ms = 2500 IOPS) 0ms + 0ms + 16K/40MB = 0.4 32K (1/0.8 ms = 1250 IOPS) 0ms + 0ms + 32K/40MB = 0.8 64K (1/1.6 ms = 625 IOPS) 0ms + 0ms + 64K/40MB = 1.6
相比第一组数据来说差距是非常的大的,因此当我们要用
另外,对于同一个磁盘(或者
问题排查
-
用工具输出磁盘相关的输出的指标,常用的有
%wa (iowait) 、%util,根据输判断磁盘I/O 是否存在异常,譬如%util 这个指标较高,说明有较重的I/O 行为; -
使用
pidstat 定位到具体进程,关注下读或写的数据大小和速率; -
使用
lsof + 进程号,可查看该异常进程打开的文件列表(含目录、块设备、动态库、网络套接字等) ,结合业务代码,一般可定位到I/O 的来源,如果需要具体分析,还可以使用perf 等工具进行trace 定位I/O 源头。
需要注意的是,%wa(iowait)的升高不代表一定意味着磁盘
网络
-
一次传输的对象过大,可能会导致请求响应慢,同时
GC 频繁; -
网络
I/O 模型选择不合理,导致应用整体QPS 较低,响应时间长; -
RPC 调用的线程池设置不合理。可使用jstack 统计线程数的分布,如果处于TIMED_WAITING 或WAITING 状态的线程较多,则需要重点关注。举例:数据库连接池不够用,体现在线程栈上就是很多线程在竞争一把连接池的锁; -
RPC 调用超时时间设置不合理,造成请求失败较多;