简介:磁盘被打满到底是真实的业务需求量上来了呢?还是有什么野进程在占用 IO? iofsstat 帮你精准定位。

编者按sysAK(system analyse kit),是龙蜥社区系统运维 SIG 下面的一个开源项目,聚集阿里百万服务器的多年运维经验,针对不同的运维需求提供了一系列工具,形成统一的产品进行服务。本文总结了实际工作中 IO 打满、IO util 高问题的处理经验,将它梳理成一套理论分析方法并形成 iofsstat 工具,集成到了sysAK 工具集里。以下将由作者带大家一道领略 iofsstat 的独特魅力。

文/李光水:系统运维SIG核心成员、 毛文安:系统运维SIG负责人。

一、 需求背景

经常碰到这样一类问题:磁盘被打满,然后 io utils 高,触发业务监控告警,磁盘使用的是 HDD,出现问题的时候 iops 已经被打到几百、bps 也已经到了上百 MB/s,然后持续个几秒钟结束,然后过个几十秒又出现,这就造成了业务监控频繁告警。业务方会苦恼,磁盘被打满了到底是真实的业务需求量上来了呢?还是有什么野进程在占用 IO。比如之前碰到一例线上问题,平常都是正常的,突然某一天发现 IO 高了很多,然后客户想知道是谁把 IO 整高了,后面通过系统的各个命令组合 +ftrace 脚本统计,找到了贡献最高的进程来自于一个与业务不相关的容器,他会定时启动,谜一般的做大量的文件拷贝动作。

二、现有工具

在定位问题这类问题的过程中,我们会通过系统的现有工具,定位具体的进程、文件或者容器,然后采取下一步措施解决问题,如停掉进程、容器并查看问题现象是否消失。一般地,如下几类工具会使用比较频繁:

  • 基于内核 diskstats 衍生的工具,如 iostat、sar-类命令的IO统计功能、vmstat-d

——可以宏观的从整个磁盘角度去统计 io 信息,如统计整盘的 iops、bps

  • 基于内核 proc/$pid/io 衍生的工具,如 pidstat -d

——可以统计到进程贡献的总体IO

  • 基于 Taskstats 衍生的工具,如 iotop

——可以统计到进程贡献的总体 IO 以及贡献的 iowait

尽管系统为我们提供了比较丰富的工具,但总有这样一种感觉:使用已有的命令,尽管知道磁盘的 IO 高了,但不知道是哪个进程贡献的;知道系统里面的某个进程贡献的 IO 高了,但又不确定这里有多少 IO 是被我关心的磁盘给消费的,也不知道这些 IO 都是在操作什么文件,总觉得哪哪都差一点儿。所以总结下来,得到如下几点诉求:

● 在磁盘 IO 被打满的情况下,希望观察是哪个进程贡献了比较多的 IO

● 系统上统计到某个进程贡献了大量的 IO,希望观察到这些 IO 最终是被哪个磁盘给消费,或者这些 IO 是在访问哪个文件,如果这个进程是来自某个容器,希望依然可以获取访问的文件以及此进程所在的容器

而本文所介绍的 iofsstat,实现了从进程角度来统计 IO 信息、文件读写信息,满足了之前提到的几个诉求,可以应用到 io utils 高、io 打满类问题的定位中。

三、iofsstat 功能介绍

3.1 统计指定磁盘的进程文件 IO

主要统计某进程对某文件贡献了多少 IO,对用户呈现的指标为进程角度+磁盘角度,磁盘角度这个毋庸置疑是为了能够看到磁盘的全貌,进程角度,是更细粒度的,可以看到对应的在这个时刻,各进程的贡献情况(PS:这里并非进程贡献的总和要等于磁盘整体的统计,因为统计的原理不一致,这里可以更多的关注两个角度之间的关联性,如在某一时刻,磁盘统计到高了,这个时候可以看到对应的这个时刻的各个进程的贡献程度),各指标如下:

进程角度:

comm:进程名、pid:进程id、cnt_rd:读文件次数、bw_rd:读文件"带宽"、cnt_wr:写文件次数、bw_wr :写文件"带宽"、inode:文件inode编号、filepath:文件路径,当在一次采集周期内由于进程访问文件很快结束情况下,获取不到文件名则为"-"。

如进程来自某个容器,在文件名后缀会显示 [containterId:xxxxxx]

磁盘角度:

xxx-stat:r_iops:磁盘总的读 iops、xxx-stat:w_iops:磁盘总的写 iops、xxx-stat:r_bps:磁盘总的读 bps、xxx-stat:w_bps:磁盘总的写 bps、xxx-stat:wait:磁盘平均 io 延迟、xxx-stat:r_wait:磁盘平均读 io 延迟、xxx-stat:w_wait:磁盘平均写 io 延迟、xxx-stat:util%:磁盘 io utils

sysak iofsstat -d vdb1 --fs 1 #间隔1秒统计一次vdb磁盘上的进程读写文件情况

2022/01/19 14:13:48
vda-stat: r_iops w_iops r_bps w_bps wait r_wait w_wait util%
0.00 98.00 0.00 91.5MB/s 946.34 0.00 946.34 93.20 comm pid cnt_rd bw_rd cnt_wr bw_wr inode filepath
dd 55937 0 0 1096 137.0MB/s 9226 /home/data/tfatsf
...

显示结果按照 bw_rd 与 bw_wr 的和做降序排列,如输出结果较多想只看某进程情况下,可以使用 -p PID 只查看指定进程

此功能基于 surftrace 开发,surftrace 是在 ftrace 基础上封装的一系列工具集,用于 trace 内核信息,当前发行版主要包含 surftrace、surfGuide 两大工具,后期还将包含 pylcc(python libbpf compile collections)。更多详情参考可点击文末 surftrace 项目代码链接查看。

3.1.1 进程、磁盘、文件信息

因为复杂的 IO 软件栈,从用户态到落盘,IO 经历了不同的数据结构上的变化,同时经过 fs 和 block 之后,IO 的生产者也可能发生变化,因此在现有的条件下,无法做到不实现内核代码就可以直接获取到这些信息,我们所关注的信息仍需要在内核中解析某些数据结构体外加推演来获取,像获取文件名、IO 大小、进程信息等,比如我们通过在 block 层解析每个 io request 就可以获取到相当饱满的信息:

通过这种方式,首先可以捕捉到所有类别的 IO,也肯定可以获取 io 对应的文件信息,但是在 buffer io 情况下,需要在内核大动干戈的去轮询所有的 task 的 files strcut 反推得到实际写这个文件的进程,而且一旦进程已经关闭了这个文件,将会推导不出进程,因此不可取,另外应尽可能的避开内核 ko,避免后续使用上受限于内核版本问题;因此考虑 fs 层是否存在可用且稳定不会变化的 tracepoint。

实际上满足功能的需求,只需要获取进程信息、IO 大小、dev 编号、文件 inode 编号就够了,而在文件系统层没有现成的符合这些需求的 tracepoint,因此考虑通过 kprobe_events 去 hook 特定函数;kprobe_events 又绕不开因为不同内核版本,数据结构会不一致,造成输入到 kprobe_events 的表达式不一致的问题,幸运的是因为 surftrace 已经帮我们解决了这个问题,我们只需要关注 kprobe 之后数据的解析,而无需关注表达式的变化。

3.1.2 如何获取文件路径

通过 3.1.1 已经获取文件 inode 编号,通过 find -inum 指定磁盘的挂载目录,或者通过 debugfs 方式,获取到文件名,但这种方式不仅耗时间也可能会耗 io;因为已经获取到了进程信息,接下来可以在 /proc/$pid/fd 过滤出来属于指定磁盘下的文件,然后比对文件的 inode 即可获取文件名,简单高效,但缺点是当比对文件过程中文件访问结束被 close 掉了,就获取不到文件名了,但这种情况一般在有问题的情况下出现概率也很低(一般关注的 IO 打满问题基本持续时间也都是秒级别)。

3.2 统计指定磁盘的进程IO贡献

主要统计某进程对某磁盘贡献了多少 IO,对用户呈现的指标为进程角度+磁盘角度,磁盘角度这个毋庸置疑是为了能够看到磁盘的全貌,进程角度,是更细粒度的,可以看到对应的在这个时刻,各进程的贡献情况(PS:这里并非进程贡献的总和要等于磁盘整体的统计,因为统计的原理不一致,这里可以更多的关注两个角度之间的关联性,如在某一时刻,磁盘统计到高了,这个时候可以看到对应的这个时刻的各个进程的贡献程度),各指标如下:

进程角度:

comm:进程名、pid:进程 id、iops_rd:进程贡献的读 iops、bps_rd :进程贡献的读bps、iops_wr:进程贡献的写iops、bps_wr :进程贡献的写bps。

磁盘角度:

同 3.1 节磁盘角度。

sysak iofsstat -d vdb 1 #间隔1秒统计一次vdb磁盘上的进程io贡献情况

2022/01/19 12:04:38
vda-stat: r_iops w_iops r_bps w_bps wait r_wait w_wait util%
0.00 118.00 0.00 104.2MB/s 976.82 0.00 976.82 95.60 comm pid iops_rd bps_rd iops_wr bps_wr
[dd] 98675 1 4.0KB/s 259 32.4MB/s
[kworker/u12:0] 91022 1 4.0KB/s 198 167.5MB/s
[jbd2/vdb1-8] 19510 0 0 1 4.0KB/s
...

显示结果按照 iops_rd 与 iops_wr 的和做降序排列,如输出结果较多想只看某进程情况下,可以使用 -p PID 只查看指定进程,假设看到的是 kworker 类进程贡献的 io 最高,可以进一步通过 3.1 节功能从 fs 角度来查看是哪个进程、哪个文件的 IO 最多。

3.2.1 实现原理

此功能基于 block 的 tracepoint,可获取到指定磁盘的来自各进程的 IO 详细信息,然后统计每个进程的 iops、bps 贡献。

四、性能开销

iofsstat 本质上是基于 ftrace 的实现,不会引发宕机,可以放心使用,由于使用的 ftrace 基本内核版本稳定,因此对内核版本依赖性也低,性能开销方面,经过统计纯 IO 统计功能(3.2 节)开销单核 1% 以下,文件 IO 统计功能(3.1节)稍微高一点,0.x%~3.x%,还在优化。

五、代码开源

iofsstat 代码将在 3 月中旬开源,敬请期待。

Gitee sysak 代码仓链接:sysak: sysAK (system analyse kit) is a toolbox contains useful tools for linux SRE, such as problem diagnosing, events monitoring/tracing, and operating of system and service

surftrace 项目代码链接:https://github.com/aliyun/surftrace

系统运维 SIG 地址:sysom SIG - OpenAnolis 龙蜥操作系统开源社区

原文链接

本文为阿里云原创内容,未经允许不得转载。

iofsstat:帮你轻松定位 IO 突高,前因后果一目了然 | 龙蜥技术的更多相关文章

  1. 轻松定位CPU飙高问题

    以下四步轻松定位CPU飙高问题: ①top pid 查看cpu耗CPU进程 ②top -Hp pid 查看该进程所有线程的运行情况,找到占用 CPU 过高的线程 pid ③ printf %x pid ...

  2. IO负载高的来源定位

    前言: 在一般运维工作中经常会遇到这么一个场景,服务器的IO负载很高(iostat中的util),但是无法快速的定位到IO负载的来源进程和来源文件导致无法进行相应的策略来解决问题. 这个现象在MySQ ...

  3. iotop,pt-ioprofile : mysql IO负载高的来源定位

    http://www.cnblogs.com/cenalulu/archive/2013/04/12/3016714.html 前言: 在一般运维工作中经常会遇到这么一个场景,服务器的IO负载很高(i ...

  4. IO负载高的来源定位 IO系列

    http://elf8848.iteye.com/category/281637 前言: 在一般运维工作中经常会遇到这么一个场景,服务器的IO负载很高(iostat中的util),但是无法快速的定位到 ...

  5. IO负载高来源定位pt-ioprofile

    1.使用top -d 1 查看%wa是否有等待IO完成的cpu时间,简单理解就是指cpu等待磁盘写入完成的时间:IO等待所占用的cpu时间的百分比,高过30%时IO压力高: 2.使用iostat -d ...

  6. 嵌入式 如何定位死循环或高CPU使用率(linux) 及性能优化

    嵌入式 如何定位死循环或高CPU使用率(linux) ln -s /mnt/nfs/_install/usr/bin/sort /usr/bin/sort awk '{print $1,$2,$14, ...

  7. 【三板斧】Java定位CPU使用高问题

    [三板斧]Java定位CPU使用高问题 1.TOP命令,查询消耗CPU高的进程号 PID,并记录下来,按下键盘"H"键,记录高消耗线程号,并将改线程号转换为十六进制 2.使用 js ...

  8. Linux系统 磁盘IO过高排查总结

    最近做的一个电商网站因为磁盘 I/O 过高导致访问速度奇慢,问题存在两个月有余未得到解决办法.此次排查原因的经验可以作下次问题的参考. 1.会看懂 top 系统命令出来的各项参数.此次是无意中发现 u ...

  9. MySQL占用IO过高解决方案【转】

    1.日志产生的性能影响: 由于日志的记录带来的直接性能损耗就是数据库系统中最为昂贵的IO资源.MySQL的日志包括错误日志(ErrorLog),更新日志(UpdateLog),二进制日志(Binlog ...

  10. linux 磁盘io利用率高,分析的正确姿势

    一.背景简介 作为一个DBA难免不了会遇到性能问题,那么我们遇到性能问题该如何进行排查呢?例如我们在高并发的业务下,出现业务响应慢,处理时间长我们又该如何入手进行排查,本片文章将分析io高的情况下如何 ...

随机推荐

  1. [转载]Linux根据关键词查找文件/函数/结构体命令整理

    本文来自博客园,作者:Jcpeng_std,转载请注明原文链接:https://www.cnblogs.com/JCpeng/p/15077235.html 一.查找文件 使用 Linux 经常会遇到 ...

  2. TomCat 的 Jenkins 提示:你的容器没有使用UTF-8解码URL地址

    1.编辑 Linux 系统的 Tomcat 安装目录的 conf 目录的 server.xml 文件 2.在 <Connector> 追加内容 URIEncoding="UTF- ...

  3. [pyplot]在同一画面上绘制不同大小的多个图像

    一.背景 做计算机应用数学作业时要求使用matplotlib库在同一张图上绘制两个图像,但是这两个图像的大小不同,百度之后发现大部分只是转载的同一篇博客,而且只能实现部分子图比例排版,并不能随意设置各 ...

  4. 前端开源项目UIRecorder录制脚本遇到的一些问题

    D:\nodejs\node_global>uirecorder init __ ______ ____ __ / / / / _/ / __ \___ _________ _________/ ...

  5. Elastic实战:彻底解决spring-data-elasticsearch日期、时间类型数据读取报错问题

    0. 引言在使用spring-data-elasticsearch读取es中时间类型的数据时出现了日期转换报错,不少初学者会在这里困惑很久,所以今天我们专门来解读该问题的几种解决方案. 1. 问题分析 ...

  6. Oracle 索引原理

    B-Tree索引 一个B树索引只有一个根节点,它实际就是位于树的最顶端的分支节点. 可以用下图一来描述B树索引的结构.其中,B表示分支节点,而L表示叶子节点. 对于分支节点块(包括根节点块)来说,其所 ...

  7. 嵌入式C语言设计学习

    由C语言到嵌入式C语言设计 1.C语言的特性 C语言,最为基本的高级编程语言,已经有许多其他的延伸.而在嵌入式设计中,主要的拓展内容就是相关的硬件设备的驱动.这部分的设计为其提供了更加灵活的应用环境. ...

  8. KingbaseES V8R3 集群运维系列 -- db vip和cluster vip管理

    ​ 案例说明: KingbaseES V8R3集群集成了DB VIP(应用连接)和Cluster VIP(集群管理),本案例描述了两种vip在集群的相关配置及集群故障时vip漂移的问题. 适用版本: ...

  9. 误删除系统超级用户(superuser)权限的恢复方式

    在使用KingbaseES数据库的时候,系统默认存在一个跟系统初始化用户同名的Superuser(默认是system用户,可更改). 这个Superuser的存在其实对于权限的管控是很有用的,但是如果 ...

  10. archlinux virtualbox使用文件共享 主机arch,客机windows8.1 windows10

    参照 https://www.cnblogs.com/cuitang/p/11263008.html 1.安装virtualbox增强功能VBoxGuestAdditions.iso (1)从virt ...