磁盘I/O这块也属于笔者比较薄弱的知识点。平时工作中基本没有很好的认知,也没有很好的检测工具来确认磁盘IO问题。
照猫画虎的从网络上找了很多文章,还是比较希望能够转化为自己的知识点。
1.基础知识先上图(图片来自极客时间 ):
我们从上到下的来分析整个层次,从应用程序发起调用到本地磁盘,基本经历了以下几个层次:
1.1 应用程序调用库函数就java程序而言,我们一般通过
// 获取指定路径的文件引用
File f = new File("filepath");
// 进程文件的修改、读取等操作...
FileInputStream fis = new FileInputStream(f);
fis.read();
1.2 调用虚拟文件系统API
在应用程序与文件系统之间横亘着一个虚拟文件系统(VFS),为什么要有这个呢?
因为文件系统类型不同,提供的API也多多少少有所不同,那么应用程序直接调用不同文件系统还是有点困难的
这是VFS便挺身而出,它定义了一组所有文件系统都支持的数据结构和标准接口,此时,应用程序直接调用VFS的API即可,VFS再调用后面的不同文件系统。
所以,VFS屏蔽了文件系统的异构性,更便于应用程序的调用。
1.3 文件系统Linux支持各种不同的文件系统,如Ext4、NFS等
具体知识点可以参考其他文章
1.4 通用块层这个还是比较陌生的一点,为什么会有这么一层呢?
大家可以先看下1.5关于磁盘块的介绍
既然底层磁盘类型都有所不同,那么类似于文件系统(不同的文件系统可能会提供不同的API调用方式,通过VFS来屏蔽不一致),这里通过通用块层来屏蔽底层不同块设备的差异带来的影响。
通用块层处于文件系统和磁盘驱动中间的一个块设备抽象层,主要有两个功能:
* 提供给文件系统标准接口,屏蔽底层不同设备块的差异;提供统一框架来管理不同设备块;
* 整理文件系统的I/O请求,通过重新排序、请求合并等方式,提高磁盘读写的效率;
1.5 磁盘块在Linux中,磁盘是作为一个块设备来管理的,以块为单位来读写数据,支持随机读写。
每个块设备被赋予两个设备号,主次设备号。主设备号用在驱动程序中,用来区分设备类型;次设备号用来给多个同类设备编号
什么是块?
磁盘读写的最小单位为扇区,扇区只有512B,如果每次磁盘读写只有一个扇区大小的话,效率低下,所以文件系统把多个连续扇区组成一个逻辑块,然后以块为单位来管理操作逻辑块。常见块大小为4KB。(固态磁盘和机械磁盘有所不同)
磁盘本身有不同类型:SATA、SCSI、IDE等
根据使用方式不同又被分为不同的架构:独立磁盘块、磁盘阵列(RAID)、网络存储集群等
2.磁盘常见性能指标如何评价磁盘各种性能高低,需要从几个常见的性能指标来看
2.1 使用率磁盘处理I/O的时间百分比。使用率高说明磁盘一直处于工作中,过高的磁盘使用率,通常意味着磁盘I/O存在性能瓶颈。
2.2 饱和度磁盘处理I/O的繁忙程度。过高的饱和度,意味着磁盘存在严重的性能瓶颈,当饱和度为100%时,磁盘无法接收新的请求。
这一点不同于使用率,当使用率100%时,磁盘依然有可能接收新的I/O请求。
2.3 IOPSInput/Output Per Second的简写,每秒的I/O请求数(这个包括input和output)
2.4 吞吐量指磁盘每秒的I/O请求大小(同样包含input和output)
吞吐量/IOPS=平均每次请求I/O大小
2.5 响应时间应用程序从发出I/O请求到接收到响应的间隔时间
3 I/O性能指标监控有了上述指标后,我们如何通过工具或者命令来监控这些指标呢
3.1 磁盘I/O性能指标监控最常用的命令就是iostat,有关iostat命令的详细介绍,可以参考笔者另一篇博客
# -d 指定只输出磁盘信息
# -x 展示磁盘信息扩展项
# 2秒输出一次
root@7bc18553126f:/tmp# iostat -d -x 2
Linux 5.10.76-linuxkit (7bc18553126f) 03/27/22 _aarch64_ (4 CPU)
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
vda 3.29 0.76 102.58 171.49 0.65 3.83 16.41 83.37 0.17 1.40 0.00 31.20 224.61 0.39 0.16
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
vda 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
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
vda 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
具体的输出信息可以通过man iostat命令来查看。
磁盘使用率%utilIOPSr/s+w/s吞吐量rKb/s+wkB/s响应时间r_await+w_await当然上述都是从磁盘的角度来展示的数据,有关数据也都是平均数据。
有关于饱和度的验证,通过iostat命令并不能得出,可以把平均请求队列长度(aqu-sz)或者读写请求完成的等待时间,与基准测试结果进行比较后进行对比,综合评估磁盘的饱和情况。
3.2 进程I/O指标监控通过iostat检测到的是全局的I/O情况,如果我们需要知道具体进程的I/O指标,则需要通过pidstat命令来查看
root@91230cc467cc:/usr/local/tomcat# pidstat -d 2
Linux 5.10.76-linuxkit (91230cc467cc) 03/28/22 _x86_64_ (4 CPU)
02:28:02 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
02:28:04 0 1 0.00 307232.00 0.00 0 java
02:28:04 0 72 0.00 2.00 2.00 0 pidstat
02:28:04 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
02:28:06 0 1 11.94 254752.24 0.00 0 java
02:28:06 0 72 0.00 1.99 1.99 0 pidstat
进程每秒读取数据大小kB_rd/s进程每秒写入数据大小kB_wr/s进程每秒取消的写请求大小kB_ccwr/s块I/O延迟iodelay
通过pidstat -d命令可以查看出哪些进程的磁盘读写请求占用比较大。
还有一个更直观的命令:iotop,类似于top命令,它可以从io角度来对进程进行排序
总结:磁盘性能指标主要就是使用率、IOPS、吞吐量以及相应时间
通过iostat命令以及pidstat可以从磁盘和进程两个维度来展示性能指标。
参考:极客时间