展示那些磁盘或分区已被使用,每个磁盘处理了多少I/O,发给这些磁盘的I/O请求要等多久才被处理。SCSI驱动则常常被命名为sda、sdb、sdc等。利用LVM,化零为整,可以对数据卷进行统一分配,动态扩容。分区或者逻辑卷被指定文件系统格式化后,挂载目录。若Linux内核注意到多个请求都指向磁盘内相邻的区域,它会把它们合并为一个大的请求。这种合并能消除第二次请求的寻道时间,以此来提高磁盘整体性能。

「 总感觉当下的生活不是想要的,总感觉一路走下去会是一个讨厌的未来,每天睁眼的一瞬间就是懊悔,昨天又浪费掉了...人生没有意义,但是要努力寻找活着的意义--------山河已无恙」
性能工具:磁盘I/O
在Linux中,我们可以通过一些性能工具评估磁盘I/O子系统的使用情况。展示那些磁盘或分区已被使用,每个磁盘处理了多少I/O,发给这些磁盘的I/O请求要等多久才被处理。
磁盘I/O介绍在学习性能工具之前,我们来了解Linux磁盘I/O系统是怎样构成的。
大多数现代Linux系统都有一个或多个磁盘驱动。SCSI驱动则常常被命名为sda、sdb、sdc等。
┌──[root@vms81.liruilongs.github.io]-[/]└─$lsblkNAMEMAJ:MIN RMSIZE RO TYPE MOUNTPOINTsda8:00200G0 disk|-sda18:10150G0 part /`-sda28:2010G0 part
磁盘通常要分为多个分区,分区设备名称的创建方法是在基础驱动名称的后面直接添加分区编号。
一般每个独立分区要么包含一个文件系统,要么包含一个交换分区。当然也可以是一个VDO卷,分区被挂载到Linux文件系统,由/etc/fstab指定。
在Linux 中,我们可以直接对磁盘进行分区,使用文件系统格式化,也使用LVM的方式来使用管理磁盘,大多数情况下,是通过LVM来管理Linux存储。利用LVM,化零为整,可以对数据卷进行统一分配,动态扩容。关于LVM(PV,VG,LV),感兴趣小伙伴可以看看我之前的博文。
分区或者逻辑卷被指定文件系统格式化后,挂载目录。即可存放应用程序要读写的文件。
当一个应用程序进行读写时,Linux内核可以在其高速缓存或缓冲区中保存文件的副本,并且可以在不访问磁盘的情况下返回被请求的信息。但是,如果Linux内核没有在内存中保存数据副本,那它就向磁盘 I/O 队列添加一个请求。
若Linux内核注意到多个请求都指向磁盘内相邻的区域,它会把它们合并为一个大的请求。这种合并能消除第二次请求的寻道时间, 以此来提高磁盘整体性能。
当请求被放入磁盘队列,而磁盘当前不忙时,它就开始为IO请求服务。如果磁盘正忙,则请求就在队列中等待,直到该设备可用,请求将被服务。这里的等待,即我们在编程中讲的IO阻塞,尤其在涉及的并发的问题中,我们常常要考虑线程I/O阻塞情况来调整线程优先级,Java在JDK1.4 的版本中,提供NIO(采用内存映射文件的方式处理,将文件或文件的一段区域映射到内存中)来提高访问效率。
磁盘I/O性能工具vmstatvmstat是一个强大的工具,它能给出系统在性能方面的总览图。除了CPU和内存统计信息之外,vmstat还可以提供系统整体上的I/O性能情况。
我们用的版本
┌──[root@vms81.liruilongs.github.io]-[/]└─$vmstat-Vvmstat from procps-ng 3.3.10┌──[root@vms81.liruilongs.github.io]-[/]└─$which vmstat/usr/bin/vmstat
vmstat超过其他I/O工具的主要优势是:几乎所有的Linux发行版本都包含该工具。同时 vmstat提供的扩展磁盘统计信息只用于内核版本高于2.5.70的Linux系统
磁盘I/O性能相关的选项和输出在使用vmstat从系统获取磁盘1/0统计信息时,要按照如下方式进行调用:
vmstat [-D] [-d] [-p partition] [interval [count]]
命令行选项
选项 描述 -D 显示Linux I/O子系统总的统计数据。它可以让你很好地了解你的IO子系统是如何被使用的,但它不会给出单个磁盘的统计数据。显示的统计数据是从系统启动.开始的总信息,而不是两次采样之间的发生量 -d 按每interval一个样本的速率显示单个磁盘的统计数据。这些统计信息是从系统启动开始的总信息,而不是两次采样之间的发生量 -p partition 按照每interval一个采样的速率显示给定分区的性能统计数据。这些统计信息是从系统启动开始的总信息,而不是两次采样之间的发生量 interval 采样之间的时间间隔 count 所取的样本总数
整个系统的IO统计数据在用-D模式运行时, vmstat提供的是系统内磁盘10系统的总体统计数据。
┌──[root@vms81.liruilongs.github.io]-[/]└─$vmstat -D1 disks2 partitions14661 total reads 33 merged reads3369384 read sectors16091 milli reading521150 writes5093 merged writes5189564 written sectors110797 milli writing0 inprogress IO 86 milli spent IO
参数 说明 disks 系统中的磁盘总数 partitions 系统中的分区总数 total reads 读请求总数 merged reads 为了提升性能而被合并的不同读请求数量,这些读请求访问的是磁盘上的相邻位置 read sectors 从磁盘读取的扇区总数(一个扇区通常为512字节) milli reading 磁盘读所花费的时间(以毫秒为单位) writes 写请求的总数 merged writes 为了提升性能而被合并的不同写请求数量,这些写请求访问的是磁盘上的相邻位置 written sectors 向磁盘写入的扇区总数(一个扇区通常为512字节) milli writing 磁盘写所花费的时间(以毫秒为单位) inprogress IO 当前正在处理的10总数。请注意,最近版本(v3.2)的vmstat在这里有个漏洞,除以1000时其结果是错误的,几乎总是得到。 milli spent IO 等待1/0完成所花费的毫秒数。请注意,最近版本(v3.2)的vmstat在这里有个漏洞,其数值为1/0花费的秒数,而非毫秒数
整个系统的IO性能情况如果你在运行vmstat时只使用了[interval]和[count]参数,其他参数没有使用,那么显示的就是默认输出。该输出中包含了三列与磁盘1/0性能相关的内容: bo, bi和wa。
┌──[root@vms81.liruilongs.github.io]-[/]└─$vmstat1 2procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- rbswpdfreebuffcachesisobiboincs us sy id wa st 100 2437082072 17486000013215510723 9500 000 2427682072 174860400032 3352 502643 9300┌──[root@vms81.liruilongs.github.io]-[/]└─$
列名 说明 bo 表示前次间隔中被写入磁盘的总块数(vmstat内磁盘的典型块大小为1024字节) bi 表示前次间隔中从磁盘读出的块数(vmstat内磁盘的典型块大小为1024字节) wa 表示等待1/0完成所消耗的CPU时间。每秒写磁盘块的速率
使用vmstat取样3个样本,时间间隔为1秒
┌──[root@vms81.liruilongs.github.io]-[/]└─$vmstat 1 3procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- rbswpdfreebuffcachesisobiboincs us sy id wa st 100 2092442072 17518280013208816023 9500 000 2090402072 175182800012 3182 476023 9500 000 2090282072 175182800058 3053 466823 9600┌──[root@vms81.liruilongs.github.io]-[/]└─$
我们可以看到,在第一秒的时候,io读取13块,写入了20块,第二读取0,写入12块,磁盘块的大小为1024字节,即系统读取速率为13/1024,等待IO的时间为O,说明当前系统IO读写空闲
每个磁盘的统计信息vmstat的-d选项显示的是每一个磁盘的I/O统计信息。这些统计数据与-D选项的数据类似
┌──[root@vms81.liruilongs.github.io]-[/]└─$vmstat-ddisk- ------------reads------------ ------------writes----------- -----IO------total merged sectorsmstotal merged sectorsmscursecsda1466133 336938416091 5237995120 5213233111242086
统计数据 说明 reads:total 读请求的总数 reads:merged 为了提升性能而被合并的不同读请求数量,这些读请求访问的是磁盘上的相邻位置 reads:sectors 从磁盘读取的扇区总数 reads:ms 磁盘读所花费的时间(以毫秒为单位) writes:total 写请求的总数 writes:merged 为了提升性能而被合并的不同写请求数量,这些写请求访问的是磁盘上的相邻位置 writes:sectors 向磁盘写人的扇区总数(一个扇区通常为512字节) writes:ms 磁盘写所花费的时间(以毫秒为单位)当前正在处理的I/O总数 IO:cur 当前正在处理的I/O总数。 10:sec 等待1/0完成所花费的秒数
[root@foundation0 ~]# vmstat -d 1 2disk- ------------reads------------ ------------writes----------- -----IO------total merged sectorsmstotal merged sectorsmscursecnvme0n1728655 656040554580 1385141015 6715558940260149sr00000000000loop0490230810000000loop193019822146000000loop2770376420000000loop38802088273000000loop44630640581904000000nvme0n1728655 656040554580 1385141015 6715558940260149sr00000000000loop0490230810000000loop193019822146000000loop2770376420000000loop38802088273000000loop44630640581904000000[root@foundation0 ~]#
┌──[root@vms81.liruilongs.github.io]-[/]└─$vmstat -p sda1 1 3sda1readsread sectorswritesrequested writes150363381024545880541472415036338102454589454148371503633810245458955414846
上面我们可以看到,对于sda1物理分区来讲,有14(545880-545894)个写提交了
虽然vmstat提供了单个磁盘/分区的统计信息,但是它只给出其总量,却不给出在采样过程中的变化率。因此,要分辨哪个设备的统计数据在采样期间发生了明显的变化就显得很困难。
iostatiostat与vmstat相似,但它是一个专门用于显示磁盘1/0子系统统计信息的工具。
iostat提供的信息细化到每个设备和每个分区从特定磁盘读写了多少个块。(iostat中块大小一般为512字节。)
此外,iostat还可以提供大量的信息来显示磁盘是如何被利用的,以及Linux花费了多长时间来等待将请求提交到磁盘。
磁盘I/O性能相关的选项和输出iostat用如下命令行调用:
iostat [-d] [-k] [-x] [devicel] [interval[count]]
与vmstat很相似,iostat可以定期显示性能统计信息。
选项 说明 -d 只显示磁盘I/O的统计信息,而不是默认信息。默认信息中还包括了CPU使用情况 -k 按KB显示统计数据,而不是按块显示 -x 显示扩展性能I/O统计信息 device 若指定设备,则iostat只显示该设备的信息 interval 采样间隔时间 count 获取的样本总数
iostat设备统计信息
┌──[root@vms81.liruilongs.github.io]-[/]└─$iostatLinux 3.10.0-693.el7.x86_64 (vms81.liruilongs.github.io)06/14/22_x86_64_(2 CPU)avg-cpu:%user%nice %system %iowait%steal%idle 2.420.002.940.010.0094.63Device:tpskB_read/skB_wrtn/skB_readkB_wrtnsda8.1824.5939.4516947482718599
统计数据 说明 tps 每秒传输次数。该项为每秒对设备/分区读写请求的次数 kB_read/s 每秒读取磁盘块的速率 kB_wrtn/s 每秒写入磁盘块的速率 kB_read 在时间间隔内读取块的总数量 kB_wrtn 在时间间隔内写入块的总数量
┌──[root@vms81.liruilongs.github.io]-[/]└─$iostat-d 1 3Linux 3.10.0-693.el7.x86_64 (vms81.liruilongs.github.io)06/14/22_x86_64_(2 CPU)Device:tpskB_read/skB_wrtn/skB_readkB_wrtnsda8.1724.3339.4016947562744300Device:tpskB_read/skB_wrtn/skB_readkB_wrtnsda9.000.0037.00037Device:tpskB_read/skB_wrtn/skB_readkB_wrtnsda0.000.000.0000┌──[root@vms81.liruilongs.github.io]-[/]└─$
当你使用-x参数调用iostat时,它会显示更多关于磁盘I/O子系统的统计信息。
┌──[root@vms81.liruilongs.github.io]-[/]└─$iostat -x-dk1 3 /dev/sda1Linux 3.10.0-693.el7.x86_64 (vms81.liruilongs.github.io)06/14/22_x86_64_(2 CPU)Device:rrqm/swrqm/sr/sw/srkB/swkB/s avgrq-sz avgqu-szawait r_await w_awaitsvctm%utilsda10.000.080.227.9624.2139.3915.570.000.231.100.210.160.13Device:rrqm/swrqm/sr/sw/srkB/swkB/s avgrq-sz avgqu-szawait r_await w_awaitsvctm%utilsda10.000.000.0015.000.0060.008.000.000.270.000.270.270.40Device:rrqm/swrqm/sr/sw/srkB/swkB/s avgrq-sz avgqu-szawait r_await w_awaitsvctm%utilsda10.000.000.008.000.0032.008.000.000.250.000.250.250.20┌──[root@vms81.liruilongs.github.io]-[/]└─$
iostat的扩展磁盘统计信息
统计数据 说明 rrqm/s 在提交给磁盘前,被合并的读请求的数量 wrqm/s 在提交给磁盘前,被合并的写请求的数量 r/s 每秒提交给磁盘的读请求数量 w/s 每秒提交给磁盘的写请求数量 rsec/s 每秒读取的磁盘扇区数 wsec/s 每秒写入的磁盘扇区数 rkB/s 每秒从磁盘读取了多少KB的数据 wkB/s 每秒向磁盘写入了多少KB的数据 avgrq-sz 磁盘请求的平均大小(按扇区计) avgqu-sz 磁盘请求队列的平均大小。 await 完成对一个请求的服务所需的平均时间(按毫秒计),该平均时间为请求在磁盘队列中等待的时间加上磁盘对其服务所需的时间 svctm 提交到磁盘的请求的平均服务时间(按毫秒计)。该项表明磁盘完成一个请求所花费的平均时间。与await不同,该项不包含在队列中等待的时间 %util 利用率
当avgqu-sz的值特别大的时候,且请求等待时间await远远高于请求服务svctm所花费时间,且利用率%util为100%的时候,表明该磁盘处于饱和状态。
sarsar可以收集Linux系统多个不同方面的性能统计信息。除了CPU和内存之外,它还可以收集关于磁盘I/O子系统的信息。
磁盘I/O性能相关的选项和输出当使用sar 来监视磁盘I/O统计数据时,你可以用如下命令行来调用它:
sar -d [interval [count] ]
通常,sar显示的是系统中CPU使用的相关信息。若要显示磁盘使用情况的统计信息,你必须使用-d选项。sar只能在高于2.5.70的内核版本中显示磁盘I/O统计数据。
显示信息进行了说明。
┌──[root@vms81.liruilongs.github.io]-[/]└─$sar -d 1 3Linux 3.10.0-693.el7.x86_64 (vms81.liruilongs.github.io)06/14/22_x86_64_(2 CPU)23:31:21DEVtpsrd_sec/swr_sec/savgrq-szavgqu-szawaitsvctm%util23:31:22dev8-07.000.0056.008.000.000.290.290.2023:31:22DEVtpsrd_sec/swr_sec/savgrq-szavgqu-szawaitsvctm%util23:31:23dev8-01.000.0010.0010.000.000.000.000.0023:31:23DEVtpsrd_sec/swr_sec/savgrq-szavgqu-szawaitsvctm%util23:31:24dev8-012.000.0096.008.000.000.330.250.30Average:DEVtpsrd_sec/swr_sec/savgrq-szavgqu-szawaitsvctm%utilAverage:dev8-06.670.0054.008.100.000.300.250.17┌──[root@vms81.liruilongs.github.io]-[/]└─$
统计数据 说明 tps 每秒传输数。该项为每秒对设备/分区进行读写的次数 rd_sec/s 每秒读取的磁盘扇区数 wr_sec/s 每秒写入的磁盘扇区数 avgrq-sz 磁盘请求的平均大小(按扇区计) avgqu-sz 磁盘请求队列的平均大小。 await 完成对一个请求的服务所需的平均时间(按毫秒计),该平均时间为请求在磁盘队列中等待的时间加上磁盘对其服务所需的时间 svctm 提交到磁盘的请求的平均服务时间(按毫秒计)。该项表明磁盘完成一个请求所花费的平均时间。与await不同,该项不包含在队列中等待的时间 %util 利用率
lsof(列出打开文件)1sof提供了一种方法来确定哪些进程打开了一个特定的文件。除了跟踪单个文件的用户外,lsof还可以显示使用了特定目录下文件的进程。同时,它还可以递归搜索整个目录树,并列出使用了该目录树内文件的进程。在要筛选哪些应用程序产生了I/O时,lsof是很有用的。
磁盘I/O性能相关的选项和输出你可以使用如下命令行调用lsof来找出进程打开了哪些文件:
1sof [-r delay] [ D directory] [ d directory] [file]
┌──[root@vms81.liruilongs.github.io]-[/]└─$yum -y installlsof
通常,lsof显示的是使用给定文件的进程。但是,通过使用 d和 D选项,它可以显示多个文件的相关信息。表6-10解释了1sof的命令行选项,它们可用于追踪I/O性能问题。
sof 命令行选项
选项 说明 -r delay 使得1sof每间隔delay秒输出一次统计数据D directory 使得1sof递归搜索给定目录下的所有文件,并报告哪些进程正在使用它们d directory 使得1sof报告哪些进程正在使用给定目录下的文件
┌──[root@vms81.liruilongs.github.io]-[/]└─$lsof-r 2D /usr/bin/COMMANDPID USERFDTYPE DEVICESIZE/OFFNODE NAMEdbus-daem539 dbus txtREG8,1442080 268592945 /usr/bin/dbus-daemonVGAuthSer544 root txtREG8,1128488 268979997 /usr/bin/VGAuthServicevmtoolsd545 root txtREG8,148976 268980000 /usr/bin/vmtoolsdfirewalld636 root txtREG8,17136 268591652 /usr/bin/python2.7tuned951 root txtREG8,17136 268591652 /usr/bin/python2.7kubelet957 root txtREG8,1 153350040 270317939 /usr/bin/kubeletcontainer961 root txtREG8,148766984 268964765 /usr/bin/containerddockerd1073 root txtREG8,196765968 268963237 /usr/bin/dockerdcontainer1735 root txtREG8,18617984 268592410 /usr/bin/containerd-shim-runc-v2container1782 root txtREG8,18617984 268592410 /usr/bin/containerd-shim-runc-v2container1853 root txtREG8,18617984 268592410 /usr/bin/containerd-shim-runc-v
统计数据 说明 COMMAND 打开该文件的命令的名称 PID 打开该文件的命令的PID USER 打开文件的用户 FD 该文件的描述符。txt表示可执行文件,mem表示内存映射文件TYPE文件类型,REG表示常规文件 DEVICE 用主设备号和次设备号表示的设备编号 SIZE 文件的大小 NODE 文件的索引节点
可以通过DEVICE来查看对应的设备位置
┌──[root@vms81.liruilongs.github.io]-[/]└─$ls -la /dev/ | grep sdbrw-rw----1 root disk8,0 Jun 12 14:58 sdabrw-rw----1 root disk8,1 Jun 12 14:58 sda1brw-rw----1 root disk8,2 Jun 12 14:58 sda2┌──[root@vms81.liruilongs.github.io]-[/]└─$
当我们通过前面的命令确定了饱和的磁盘设备。那么我们可以通过lsof来根据磁盘找到对应的文件,从而确认对应的PID
