diff --git a/docs/iomonitor_instruction.md b/docs/iomonitor_instruction.md new file mode 100644 index 0000000000000000000000000000000000000000..5c2cc2e608ab42ff011fccc83cefd17ee2ae0091 --- /dev/null +++ b/docs/iomonitor_instruction.md @@ -0,0 +1,357 @@ +# 1 背景介绍 +目前大多数监控集成了OS的IO相关指标,如await、util、tps、bps等,当某个或某些指标突然飚高的时候就会认为出现了IO问题,随即找OS同学定位。一般来说,问题的排查也仅止步于此,一是因为从监控发现异常的时候,问题现场早就已经丢失,没法再去针对性地抓取更多帮助信息;二是虽然监控指标丰富多样,但是它们之间又都是彼此孤立的存在,没有体现出与问题的强关联性;这正是目前的系统运维面临的一大困境。 +![输入图片说明](https://foruda.gitee.com/images/1713420744831318260/ba8fce04_7352624.png "1653722232926-6beb0d8a-6905-4205-8b0e-98d646a5ab9c.png") +# 2 架构介绍 +作为sysom监控中心的监控子系统之一的ioMonitor,主要聚焦于IO延迟高、IO夯、io burst、iowait高等几类出现频次高的问题,旨在更好地去捕捉IO子系统相关的异常,并且能够进一步深挖分析出根因。基于目前已经实现的应对IO延迟高、IO夯、IO Burst这几类问题的诊断工具——iosdiag,考虑ioMonitor通过常态化监控IO指标,识别其中异常,触发诊断工具运行,实现在用户侧“发现问题->诊断问题->根因分析”的自闭环。 +由于不同的业务场景,关注的监控阈值会不一样,如果统一一个静态阈值覆盖各种场景,很可能引起异常的误报或者漏报,因此本工具通过动态阈值来识别异常。ioMonitor总体上由四个模块组成,架构图如下图所示: +![输入图片说明](https://foruda.gitee.com/images/1713420935053772559/60f6aca9_7352624.png "1712738844122-5fed045e-6a26-475e-af2f-4540e164a865.png") + +**IO指标监控**:从系统获取IO的关键指标,例如await、util、tps、iops、qu-size、iowait。 + +**异常识别**:当采集到的IO指标大于动态阈值时,判定为异常,因此异常识别的核心在于动态阈值的计算,具体算法将在4.1.2节解释。 + +**异常诊断**:根据不同的指标异常,触发对应的诊断工具,并且会对触发频率做了一定的限制。 + +**数据清洗&&可视化**:根据诊断结果呈现出可视化的输出,给出根因和解决建议。 +# 3 安装使用 +## 3.1 使用前提 + +1. 安装sysak; +2. IO夯、IO延迟监测功能会依赖内核版本,遇到不支持的内核版本可能存在功能缺失情况,开启前请确定当前内核版本是否支持,具体支持情况如下: + +| 功能 | 支持的内核版本 | +| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| IO夯监测 | 3.10.0-1062.1.1.el7.x86_64
3.10.0-1062.1.2.el7.x86_64
3.10.0-1062.12.1.el7.x86_64
3.10.0-1062.18.1.el7.x86_64
3.10.0-1062.4.1.el7.x86_64
3.10.0-1062.4.2.el7.x86_64
3.10.0-1062.4.3.el7.x86_64
3.10.0-1062.7.1.el7.x86_64
3.10.0-1062.9.1.el7.x86_64
3.10.0-1062.el7.x86_64
3.10.0-1127.10.1.el7.x86_64
3.10.0-1127.13.1.el7.x86_64
3.10.0-1127.18.2.el7.x86_64
3.10.0-1127.19.1.el7.x86_64
3.10.0-1127.8.2.el7.x86_64
3.10.0-1127.el7.x86_64
3.10.0-1160.11.1.el7.x86_64
3.10.0-1160.15.2.el7.x86_64
3.10.0-1160.2.1.el7.x86_64
3.10.0-1160.2.2.el7.x86_64
3.10.0-1160.36.2.el7.x86_64
3.10.0-1160.6.1.el7.x86_64
3.10.0-1160.el7.x86_64
3.10.0-514.6.2.el7.x86_64
3.10.0-693.11.1.el7.x86_64
3.10.0-957.1.3.el7.x86_64
3.10.0-957.10.1.el7.x86_64
3.10.0-957.12.1.el7.x86_64
3.10.0-957.12.2.el7.x86_64
3.10.0-957.21.2.el7.x86_64
3.10.0-957.21.3.el7.x86_64
3.10.0-957.27.2.el7.x86_64
3.10.0-957.5.1.el7.x86_64
3.10.0-957.el7.x86_64
4.18.0-305.19.1.an8.x86_64
4.18.0-305.25.1.an8_4.x86_64
4.18.0-305.28.1.an8_4.x86_64
4.18.0-305.7.1.an8_4.x86_64
4.18.0-305.an8.x86_64
4.18.0-348.2.1.an8_4.x86_64
4.18.0-372.32.1.an8_6.x86_64
4.19.91-18.al7.x86_64
4.19.91-19.1.al7.x86_64
4.19.91-19.2.al7.x86_64
4.19.91-21.2.al7.x86_64
4.19.91-21.al7.x86_64
4.19.91-22.1.al7.x86_64
4.19.91-22.2.al7.x86_64
4.19.91-23.1.al7.x86_64
4.19.91-23.4.an8.x86_64
4.19.91-23.al7.x86_64
4.19.91-24.1.al7.x86_64
4.19.91-24.8.an8.x86_64
4.19.91-24.9.an8.x86_64
4.19.91-24.al7.x86_64
4.19.91-25.1.al7.x86_64
4.19.91-25.1.an8.x86_64
4.19.91-25.6.al7.x86_64
4.19.91-25.6.an8.x86_64
4.19.91-25.7.al7.x86_64
4.19.91-25.7.an8.x86_64
4.19.91-25.8.al7.x86_64
4.19.91-25.8.an8.x86_64
4.19.91-26.1.al7.x86_64
4.19.91-26.1.an8.x86_64
4.19.91-26.2.al7.x86_64
4.19.91-26.2.an8.x86_64
4.19.91-26.3.al7.x86_64
4.19.91-26.3.an8.x86_64
4.19.91-26.4.al7.x86_64
4.19.91-26.4.an8.x86_64
4.19.91-26.5.al7.x86_64
4.19.91-26.5.an8.x86_64
4.19.91-26.6.al7.x86_64
4.19.91-26.6.an8.x86_64
4.19.91-26.al7.x86_64
4.19.91-26.an8.x86_64
4.19.91-27.1.al7.x86_64
4.19.91-27.2.al7.x86_64
4.19.91-27.3.al7.x86_64
4.19.91-27.4.al7.x86_64
4.19.91-27.5.al7.x86_64
4.19.91-27.6.al7.x86_64
4.19.91-27.7.al7.x86_64
4.19.91-27.al7.x86_64
5.10.112-11.1.al8.x86_64
5.10.112-11.2.al8.x86_64
5.10.112-11.al8.x86_64
5.10.134-12.1.al8.x86_64
5.10.134-12.2.al8.x86_64
5.10.134-12.al8.x86_64
5.10.134-13.1.al8.x86_64
5.10.134-13.al8.x86_64.ko
5.10.134-14.al8.x86_64.ko
5.10.134-15.1.al8.x86_64
5.10.134-15.2.al8.x86_64
5.10.134-16.1.al8.x86_64
5.10.134-16.al8.x86_64
5.10.23-5.al8.x86_64
5.10.23-6.al8.x86_64
5.10.60-9.al8.x86_64
5.10.84-10.1.al8.x86_64
5.10.84-10.2.al8.x86_64
5.10.84-10.3.al8.x86_64
5.10.84-10.4.al8.x86_64
5.10.84-10.al8.x86_64 | +| IO延迟监测 | centos7.6及其以上版本
4.19及其以上版本,如alinux2、anolis | + +## 3.2 用法介绍 +安装完sysak后,在终端执行`sysak ioMonitor -h`后,会显示帮助信息: +``` +usage: sysak ioMonitor [-h] [-y YAML_FILE] [-s SET_CFG] [-r] [-o] [-t TIMEOUT] [-d] + [-a ANALYSIS_FILE] + +start ioMonitor. + +optional arguments: + -h, --help show this help message and exit + -y YAML_FILE, --yaml_file YAML_FILE + Specify the socket pipe for data upload and exception + log path + -s SET_CFG, --set_cfg SET_CFG + set monitor cfg, like -s 'xxxx=xxx,xxx=xxx' iowait, + The min cpu-iowait not report exceptions(1~100, + default 5). await, The min partition-await not report + exceptions(N ms, default 10). util, The min partition- + util not report exceptions(1~100, default 20). bps, + The min partition-bps not report exceptions(bytes, + default 30MB). iops, The min partition-iops not report + exceptions(default 150). cycle, The cycle of + Monitoring data collection(default 500ms). diagIowait, + Disable or enable diagnose while reporting iowait + exceptions(default on). diagIolat, Disable or enable + diagnose while reporting latency exceptions(default + on). diagIoburst, Disable or enable diagnose while + reporting ioburst exceptions(default on). diagIohang, + Disable or enable diagnose while reporting iohang + exceptions(default on). + -r, --reset_cfg Reset cfg to default + -o, --only_set_cfg Only set cfg + -t TIMEOUT, --timeout TIMEOUT + Monitoring/Diagnose duration + -d, --diagnose_mode Diagnose mode + -a ANALYSIS_FILE, --analysis_file ANALYSIS_FILE + Store diagnosis result + +e.g. + sysak ioMonitor -y [yaml_file] + Start ioMonitor + sysak ioMonitor -y [yaml_file] --reset_cfg --only_set_cfg + Only reset cfg to default + sysak ioMonitor -y [yaml_file] -s 'iowait=10,iops=200,diagIowait=on' --only_set_cfg + Only set min-iowait&&min-iops and disable iowait diagnose to config. +``` +各个参数的详细解释如下: + +- **-y [yaml_file]**:默认的yaml文件路径为“/etc/sysak/base.yaml”,可以修改或者指定为别的yaml文件,yaml文件中比较重要的是outline配置,指定了socket数据上传管道: +```yaml +outline: + - /var/sysom/outline +``` + +- **-s 'xxxx'**:-s 参数支持对配置文件各个参数的直接配置,覆盖掉ioMonitor默认配置。ioMonitor默认配置文件路径为“/run/ioMon/ioMonCfg.json”,默认会关闭IO-Lantency,IO-Burst,IO-Wait,IO-Hang监测(对应diagIolat,diagIoburst,diagIowait,diagIohang为"off"),默认配置如下: +```json +{ + "diagIoburst": "off", + "diagIolat": "off", + "diagIowait": "off", + "iowait": 5, + "await": "2", + "util": 20, + "bps": 31457280, + "iops": "150", + "diagIohang": "off", + "cycle": 1000 +} +``` +具体各配置字段含义如下: + +| 参数名称 | 取值范围/默认值/单位 | 参数说明 | +| --- | --- | --- | +| iowait | [0,100]/5/百分比 | 上报iowait指标异常的最小阈值,即指标低于此值,不作为异常上报,同时在触发iowait高诊断时,低于此阈值的信息将会被忽略 | +| await | 正整数/5 /毫秒 | 上报await指标异常的最小阈值,即指标低于此值,不作为异常上报,同时在触发io延迟高诊断时,延迟低于此阈值的信息将会被忽略 | +| util | [0,100]/20/百分比 | 上报io util指标异常的最小阈值,即指标低于此值,不作为异常上报,同时也会屏蔽util没有达到此阈值时发生的ioburst异常 | +| bps | 正整数/31457280/字节数 | 上报io bps指标异常的最小阈值,即指标低于此值,不作为异常上报,同时在触发ioburst诊断时,bps低于此阈值的信息将会被忽略 | +| iops | 正整数/150 / | 上报iops指标异常的最小阈值,即指标低于此值,不作为异常上报,同时在触发ioburst诊断时,iops低于此阈值的信息将会被忽略 | +| cycle | 正整数/1000/毫秒 | 监控指标采集周期 | +| diagIowait | (on或者off)/off/ | 配置iowait诊断是否使能,配置on时,检测到iowait高时会自动触发诊断,分析异常原因,默认是off | +| diagIolat | (on或者off)/off/ | 配置io延迟诊断是否使能,配置on时,检测到io延迟高时会自动触发诊断,分析异常原因,默认是off | +| diagIoburst | (on或者off)/off/ | 配置io burst诊断是否使能,配置on时,检测到突发的io burst时会自动触发诊断,分析异常原因,默认是off | +| diagIohang | (on或者off)/off/ | 配置iohang诊断是否使能,配置on时,检测到io夯时会自动触发诊断,分析异常原因,默认是off | + +- **-r, --reset_cfg**:配置设置成默认值并开启ioMonitor。 +- **-o, --only_set_cfg**: 只更改配置但不开启ioMonitor。 +- **-d, --diagnose_mode**:切换为一键诊断模式。 +- **-t TIMEOUT, --timeout**:设置监控/一键诊断时长,当模式为监控模式且该值等于0时,则会是常态化持续监控。 +- **-a ANALYSIS_FILE, --analysis_file ANALYSIS_FILE**:保存一件诊断的结果的文件路径。 + +举例来说,如需屏蔽iowait为10、iops为200以下的异常,同时关闭iowait诊断功能,其他参数不变: +``` +sysak ioMonitor --set_cfg 'iowait=10,iops=200,diagIowait=off' +``` +如恢复到监控自带的默认参数: +``` +sysak ioMonitor --reset_cfg +``` + +在不确认参数配置为何值的情况下,可以考虑使用默认配置,观察后续上报异常情况,可以从监控中得到的异常信息来确认是否需要自定义设置。 +# 4 实现原理 +## 4.1 指标采集及计算 +### 4.1.1 指标采集 +每间隔cycle毫秒会采集并计算owait、iops、bps、qusize、await、util的值,并检查是否有异常,具体的采集及计算方式如下: + +| 参数名称 | 参数含义 | 采集路径 | 计算方式 | +| --- | --- | --- | --- | +| iowait | CPU在等待磁盘I/O操作完成耗时 | /proc/stat | 相邻两次采样的累计IO等待时间差值/累计总CPU时间片差值 | +| await | I/O延迟 | /proc/diskstats | 相邻两次采样时段内,读写操作花费的总毫秒数/读写IO总数 | +| util | I/O利用率 | /proc/diskstats | 相邻两次采样时段内,花在IO操作上的毫秒数/采样间隔 | +| bps | 每秒传输的字节数 | /proc/diskstats | 相邻两次采样时段内,读写扇区总次数*512/采样间隔 | +| iops | 每秒完成的I/O数 | /proc/diskstats | 相邻两次采样时段内,读写完成次数/采样间隔 | +| qusize | 相当于iostat的avgqu-sz,表示I/O队列的平均请求数 | /proc/diskstats | 相邻两次采样时段内,读写操作花费的加权毫秒数/采样间隔 | + +### 4.1.2 动态阈值计算 +为了能够识别秒级的IO异常行为,需要将系统中采集到的各个孤立的IO指标聚合起来,形成对IO Burst等问题的监控能力,这个过程的核心在于动态阈值的计算,动态阈值经过三步计算得到:滑动窗口阈值计算,补偿阈值计算以及最小阈值计算。 +#### 4.1.2.1 滑动窗口阈值计算 +IO指标其实是一种时间序列,而且一般地,在一个时间区间内,可以认为绝大部分时间是没有异常的,因此序列形成的曲线趋势是趋于平稳的,当出现异常的时候,会产生一个明显偏离平稳趋势的尖峰,因此第一步要做的就是通过本节计算得到的基础阈值把IO指标中的尖峰毛刺筛选出来。 +计算思路: + +- 取固定窗口大小(目前代码中窗口window大小设置的为100)的一组数据进行计算,计算当前窗口平均值`Mavg`。 +- 获取此窗口数据集的最大值`max`与最小值`min`,然后记录下每次的`MAX((max-Mavg), (Mavg-min))`值作为`thresh`,并同时通过历史`thresh`的平均值`threshAVG`,重新计算`threshAVG`,以`threshAVG`作为本次的基础阈值。 +- 下一次的基础阈值按照步骤1、2以此类推。 + +![输入图片说明](https://foruda.gitee.com/images/1713420971098287038/dbf6f916_7352624.png "1653745057562-475f6c04-6630-4e59-9492-f931f044f6ae.png") +#### 4.1.2.2 补偿阈值计算 +补偿阈值,是为了消除误报而存在,尝试推断IO指标在平稳状态下的一个波动范围,获取补偿值,叠加到基础阈值上,作为新的异常判断阈值。 + +由于基础阈值曲线(如下图中的黄色曲线)的平稳程度,可以反应真实IO指标数据的波动情况,此处通过统计一个窗口内(目前代码中窗口大小设置的为1.5倍的window大小)基础阈值的变化趋势,采用历史基础阈值作为补偿值。 + +在常稳状态下的补偿值未计算出来之前,将此窗口内最大的基础阈值为补偿值,当进入一个新窗口时则重置为当前基础阈值。如果基础阈值持续1.5个window窗口单调下降,说明IO压力可能回归常稳态化了,此时丢弃掉超过基础阈值*1/10的点,计算常稳态补偿值,如果已经统计了1.5个window大小的稳定的数据,则可取此窗口内常稳态阈值补偿值数据集的最大值`max`与最小值`min`,计算`MAX((max-stableThreshAvg), (stableThreshAvg-min))`值作为常稳态阈值补偿值。一旦遇到基础阈值曲线不再持续单调递减时,则重新统计。 +![输入图片说明](https://foruda.gitee.com/images/1713420996927928020/47349462_7352624.png "1653745707160-dfa0e58a-fae9-434e-8a04-d0250586d88c.png") +#### 4.1.2.3 最小阈值 +最小阈值,是一个静态阈值(配置文件中设置),作用是屏蔽阈值以下的异常,有时上报的异常可能还没有影响到业务(如下图所示),需要将这些业务不关心的异常进行屏蔽,因此最终实际的异常判定中,判定阈值为:`MAX(最小阈值,(基础阈值+补偿值))`,最小阈值在监控有一套默认值,也支持重置最小阈值。需要注意的是,如果当前指标值大于最小阈值,则计算动态阈值时不用添加补偿阈值。 +![输入图片说明](https://foruda.gitee.com/images/1713421020739700823/b086991d_7352624.png "1653745921057-7c605e16-b887-40c2-af4f-ad6961c799cf.png") +## 4.2 异常识别 +### 4.2.1 iowait异常 +iowait异常识别过程如下: + + 1. 判断当前iowait采集值是否大于最小阈值,如果大于则不用添加补偿阈值来计算动态阈值; + 2. 更新iowait平均值,取动态阈值和最小阈值中的最小值作为当前iowait阈值; + 3. 如果当前iowait采集值大于iowait阈值,检查iowait监测是否还是使能状态并且当前是否可以发起诊断,均可之后便能发起诊断,iowait阈值取`min(当前iowait采集值*0.25,iowait最小阈值)`; + 4. 更新iowait动态阈值。 +### 4.2.2 IO-Burst异常 +IO-Burst异常识别过程如下: + + 1. 首先如果util大于最小阈值,则会取消阈值补偿。检查util异常时,首先阈值会取动态阈值和最小阈值中的较小值。当当前uitl大于阈值时,则会检查是否有IO-Burst情况。 + 2. 此时,需要计算6个参数分别是: + +| 参数名 | 参数含义 | 计算方式 | +| --- | --- | --- | +| bpsLowW | bps最小阈值 | 配置文件中的bps阈值 | +| bpsHighW | bps最大阈值 | max(bps动态阈值,bpsLowW) | +| bpsMiddW | bps中间值 | max(bpsLowW, bpsHighW/2) | +| iopsLowW | iops最小阈值 | 配置文件中的iops阈值 | +| iopsHighW | iops最大阈值 | max(iops动态阈值,iopsLowW) | +| iopsMiddW | iops中间值 | max(iopsLowW, iopsHighW/2) | + + 3. 如果当前 `bps采集值>bpsMiddW` 或者 `iops采集值>iopsMiddW `,则可判断发生了ioburst情况。并且如果当前 `bps采集值>bpsHighW` 或者 `iops采集值>iopsHighW `,则可进一步判断是否是bps过高和iops高的情况,只要存在其一,检查ioburst监测是否还是使能状态并且当前是否可以发起诊断,均可之后便能发起诊断,此时bps阈值取`max(当前bps采集值*0.25,bpsLowW)`,iops阈值取`max(iops*0.7,iopsLowW)`。 + 4. 更新util,iops,bps的动态阈值。 +### 4.2.3 IO-Hang异常 +如果util高,又检测不到IO-Burst异常,则检查是否是IO-Hang异常: + + 1. 如果`util >= 100,qusize >= 1,并且iops < 50`,那么初步认为有IO-Hang情况。 + 2. 检查iohang监测是否还是使能状态并且当前是否可以发起诊断,均可之后便能发起诊断。 +### 4.2.4 IO-Delay异常 +IO延迟高异常识别过程如下: + + 1. 取`max(await最小阈值,await动态阈值)`作为阈值,如果当前await采集值大于此阈值,检查io延迟监测是否还是使能状态并且当前是否可以发起诊断,均可之后便能发起诊断。await阈值取值`max(await采集值*0.4,await最小阈值)`。 + 2. 更新await的动态阈值。 + + 如想方便获取监控数据,可直接运行以下curl命令从被监控机器获取数据,并放入html文件: +`curl -o latency.html "[http://127.0.0.1:8400/query/baseQ?gmt=0&selTable=sysom_iolatency&timeLen=600"]` + + 需要注意的是: + - 其中“latency.html"可命名为其他文件名; + - 如果从别的机器执行curl命令,"127.0.0.1"则需替换为实际被监控机器的IP; + - "timeLen"可替换成实际想获取距今多久的监控数据,单位为分钟。 + +通过浏览器打开生成的latency.html文件,一个典型示例如下: +![输入图片说明](https://foruda.gitee.com/images/1713421060807655533/8ae99072_7352624.png "1711506469627-42145457-2508-48a1-a510-f839b285d06e.png") +如果节点可以被sysom纳管,则可以通过sysom拉取指标并且绘制动态面板,展示各个进程的IO延迟情况: +![输入图片说明](https://foruda.gitee.com/images/1713421255845616779/181d7c13_7352624.png "1711526912262-22c050c2-6b12-4d2f-9de6-9aae381a14a6.png") +具体各个字段的含义解读: + +| 字段名 | 字段含义 | +| --- | --- | +| diskname | 磁盘盘符 | +| iotype | io类型 | +| pid | 进程ID | +| ppid | 线程ID | +| comm | 进程名 | +| queue_id | 队列编号 | +| block | block层延迟(us) | +| diver | 驱动延迟(us) | +| disk | 磁盘处理延迟(us) | +| complete | IO从磁盘完成之后中断返回驱动延迟(us) | +| done | IO结束后,回调去唤醒前台的IO的延迟(us) | +| maxdelay_component | 此IO的延迟最大的组件 | +| max_delay | 延迟最大的组件的延迟(us) | +| total_delay | 总延迟(us) | +| issue_cpu | 发起此IO的CPU | +| respond_cpu | 响应IO完成之后磁盘中断的CPU | +| soft_interrupt_cpu | 磁盘IO完成后执行软中断的CPU | +| sum_datalen | 被聚合的IO访问磁盘的总数据量 | +| datalen | 被聚合的IO访问磁盘的平均数据量 | +| count | 被聚合IO数目 | + +其他说明: + +1. 如果只显示一个CPU编号,说明发起IO和执行中断的CPU相同,要注意也有磁盘是没有软中断流程的; +2. 大流量延迟场景下,容易一次性返回告警事件过多,存储和计算压力过大。所以设计了IO信息的聚合机制,监控产生的一条数据可能是一个周期内有条件被聚合的许多IO的关键信息整合而来。 +## 4.3 智能诊断 +监测出现异常的时候,能够及时到现场抓取关健信息、分析信息、定位问题原因,尤为重要,这几个步骤看似简单,但是在实际的人为操作过程中并非一帆风顺;比如,知道异常了,决定抓哪些关键信息、怎么抓,很关键,拿捏不定,可能现场就没了,抓太少又不够分析,抓太多又给机器带来更多开销,雪上加霜,而且事后分析困难;这每一步无疑需要运维人员具备更多相关领域的知识储备;为了解决这些困扰,本监控具备了传统监控所不具备的异常诊断功能: + +- 监控到io burst异常后,自动触发IO burst诊断工具运行,抓取关键信息 +- 监控到io 夯异常后,自动触发IO夯诊断工具运行,抓取关键信息 +- 监控到IO高延迟异常后,自动触发IO延迟诊断工具运行,抓取关键信息 +- 监控到iowait高异常后,自动触发iowait高诊断工具运行,抓取关键信息 + +对于诊断触发的频率也通过上报间隔(reportInterval)和触发间隔(triggerInterval)两个参数加以限定: + +- **triggerInterval**:触发间隔。当上报间隔配置值为0,并且上次诊断距现在已有大于诊断触发间隔的时时长,那么就具备发起诊断的条件。 +- **reportInterval**:上报间隔。如果配置值不等于0,需要满足在一个窗口内(self.window=100)上报次数超过该配置值和上次诊断距现在已有大于诊断触发间隔的时长两个条件,才具备发起诊断的条件。 + +关于各个监控项的上报间隔和触发诊断间隔配置如下: + +| **异常事件** | **triggerInterval** | **reportInterval** | **诊断阈值** | **诊断时长** | +| --- | --- | --- | --- | --- | +| iowait | 0 | 60 | iowait动态阈值 | 每5秒1次,共持续45秒 | +| iohang | self.window*5(500) | 10 | 3000ms | 持续10秒 | +| ioutil | 60 | 0 | iops,bps动态阈值 | 每秒输出流量前5的进程,持续40秒 | +| iolatency | 60 | 0 | await动态阈值 | 持续20秒 | + +举例来说,发起iohang诊断需要在一个窗口内监测到10次IO夯异常事件,并且距离上次诊断已超过500s,而发起iolatency诊断只用监测到IO延迟异常后,距离上一次发起IO延迟诊断过去了超过1分钟即可。 +## 4.4 根因分析 +在诊断工具抓取了信息之后,面对各种信息,从何处着手,也令人困扰,因此瞄准瞄准方向,进行专业的分析、拨丝抽茧地从中筛查跟问题相关的线索显得非常重要;本监控则具备这个抽丝剥茧的分析能力,并且能够汇报跟问题相关的结论性信息: + +- 对于IO Burst异常,经过分析后,在监控的日志拦中汇报异常期间贡献IO最多的进程,其中极具特色的是,对于写buffer io后由kworker刷脏的情况,也能分析出来是哪个进程在写buffer io +- 对于IO夯异常,经过分析后,在监控的日志拦中汇报当前IO夯在哪个位置 +- 对于IO高延迟异常,经过分析后,在监控的日志拦中汇报异常期间IO的延迟分布,输出IO延迟最大的路径 +- 对于iowait高异常,经过分析后,在监控的日志拦中汇报触发iowait高的进程、以及触发原因 + +![输入图片说明](https://foruda.gitee.com/images/1713421317524135068/3c561f42_7352624.png "1660200992828-abe42db4-0d3b-450b-a94b-f790c168f2be.png") +# 5 监控面板说明 +## 5.1 IO异常事件监控 +### 5.1.1 IOWait高监控 +**High IOwait(count/min)面板**:每分钟出现iowait高的次数 +![输入图片说明](https://foruda.gitee.com/images/1713421524463640049/b1261f0c_7352624.png "1662632850487-d03f7dcb-c8fd-4c10-ab0c-0296494d22f0.png") +**IOwait logs面板**:iowait高的原因分析,展示reason信息、solution信息; +![输入图片说明](https://foruda.gitee.com/images/1713421570880276050/086ee45d_7352624.png "1662632907755-c8ad470c-879e-47be-b72d-92da65be422c.png") + +- reason为引起iowait高的具体原因,展示引起iowait高的前top3的进程信息,每一条信息格式如下: + +[序号. 某进程,等待IO多长时间,导致多少iowait占比,等待IO原因;] + +例如: +| 1.task[dd:21453:21453], wait 905.568ms, contribute iowait 33.42% due to 'Too many dirty pages'| +| --- | + +表示‘top1. [进程名:dd,tgid:21453,pid:21453],在1秒时间中等待IO 905ms,导致了系统33.4%的iowait比率,等待IO的原因是系统脏页太多(Too mang dirty pages)’ + +- solution为处理建议 +### 5.1.2 IO Burst监控 +**IO-Burst(count/min)面板**:表示每磁盘,每分钟出现IO-burst次数 +![输入图片说明](https://foruda.gitee.com/images/1713421593429882776/9546038e_7352624.png "1662633017206-a2c618e9-0478-4118-83ac-b892d02e26d2.png") +**IO-Burst logs面板**:引发io burst的原因分析,展示reason信息、solution信息; +![输入图片说明](https://foruda.gitee.com/images/1713421613140508969/0597afa0_7352624.png "1662633095854-bdb3500e-8528-4291-9140-4f60398ede27.png") + +- reason为引起iowait高的具体原因,展示引发io burst的前top3的进程信息,每一条信息格式如下: + +[序号. 某进程,以多大iops/bps访问磁盘;] + +例如: + +| 1. task[kworker/u4:2:12025], access disk vda with iops:5389, bps:622.3MB/5s(Write bio from: dd:21453:21453 Wrbw 562.0MB/5s disk vda1 file /mnt/host/root/test21;) | +| --- | + +表示‘top1. [进程名:kworker,tgid:2,pid:12025],在5秒内访问vda磁盘5389次io、622.3MB数据(实际IO源头为,用户态的dd程序在5秒写了562MB数据,目标文件为/mnt/host/root/test21)’ + +- solution为处理建议 +### 5.1.3 IO Delay监控 +**High IO-Delay(count/min)面板**:表示每磁盘,每分钟出现高IO延迟的次数 +![输入图片说明](https://foruda.gitee.com/images/1713421711462912310/b77ff121_7352624.png "1662633823226-e95a6a06-2a67-4763-ae14-74a320dd3926.png") +**IO-Delay logs面板**:引发IO高延迟的原因分析,展示reason信息、solution信息; + +- reason为引起IO高延迟的具体原因,信息格式如下: + +[总体原因(IO延迟消耗高的具体组件、组件延迟多大以及占总体延迟的占比)] + +例如: + +| IO burst occurs, Too mang IO backlogs(disk avg/max lat:166.67/765.443 ms, lat percent:53.486%, OS dispatch avg/max lat:144.939/1226.279 ms, lat percent:46.512% | +| --- | + +表示‘发生IO Burst,大量IO积压(IO在磁盘的平均延迟/最大延迟分别为:166/756ms,占IO总延迟53.4%,OS派发IO平均延迟/最大延迟分别为:144/1226ms,占IO总延迟46.5%)’ +![输入图片说明](https://foruda.gitee.com/images/1713421750797158422/58636522_7352624.png "1662633916273-f57d8cd9-2ad0-439a-b9ea-e000745fde47.png") + +- solution为处理建议 +### 5.1.4 IO HANG监控 +**IO-Hang(count/min)面板**:表示每磁盘,每分钟出现IO HANG的次数 +![输入图片说明](https://foruda.gitee.com/images/1713421796955428747/4ab25187_7352624.png "1662637204189-1c52a429-a8d7-4bde-b94c-081d279e1aa0.png") +**IO-Hang logs面板**:引发IO高延迟的原因分析,展示reason信息,由于此面板信息涉及到内核ko,因此默认关闭状态,即无数据输出。如监控iohang现象一直在,可通过IO-Hang监控项查看,通过配置使能之后,也是可以立马得到信息的; +![输入图片说明](https://foruda.gitee.com/images/1713421817420847646/43ec705f_7352624.png "1662637258388-755b7653-34f2-4920-b010-dcf09bed7bc9.png") + +- reason为IO HANG的具体原因,信息格式如下: + +[总体原因(具体原因、HANG住了多长时间),第一次HANG的IO信息(IO产生时间,IO类型,扇区号)] + +例如: +| Disk hang(Waitting for disk handle, avg/max delay:327.54/327.54 ms), first hang[time:2022/09/07 17:41:29, iotype:WRITE, sector:20226032] | +| --- | + +表示‘IO HANG在磁盘上(等待磁盘处理,平均HANG/最大HANG住时间为:327/327ms),首次HANG住的IO为2022/09/07 17:41:29产生,为写IO,访问磁盘的扇区号为20226032’ +## 5.2 IO通用指标监控 +### 5.2.1 iowait(%):平均每分钟系统iowait值 +![输入图片说明](https://foruda.gitee.com/images/1713421847755960264/972ae74b_7352624.png "1662638104087-8322b69a-3c6f-4c06-988e-5898f7654022.png") +### 5.2.2 util(%):平均每分钟磁盘的繁忙比重 +![输入图片说明](https://foruda.gitee.com/images/1713421876005997020/e548588c_7352624.png "1662638132507-50d8f53d-ccea-4300-ba31-a29e12e69ca2.png") +### 5.2.3 await(ms):平均每分钟系统IO的延迟 +![输入图片说明](https://foruda.gitee.com/images/1713421950057981808/cb9cb65c_7352624.png "1662638152122-7e1dce8f-957b-49e9-99eb-409ee6795707.png") +### 5.2.4 bps(KB/s):平均每分钟访问磁盘的IO吞吐 +![输入图片说明](https://foruda.gitee.com/images/1713421988663800902/208ab425_7352624.png "1662638173644-da61f90f-d4ac-4660-ba07-77fb781bc766.png") +### 5.2.5 iops:平均每分钟访问磁盘的IO次数 +![输入图片说明](https://foruda.gitee.com/images/1713422013854839551/df04c005_7352624.png "1662638196083-c522b661-9411-436b-95b6-475815a380c0.png") +### 5.2.6 qsize:平均每分钟队列中未完成的IO数 +![输入图片说明](https://foruda.gitee.com/images/1713422216743847626/08fb2ecf_7352624.png "1662638213256-a9e9c2c3-93ec-490a-97ef-afe41f866d55.png") +# 6 应用案例 + +- 客户机器偶现系统盘被大吞吐量io打满问题,使用iotop没有抓到大吞吐量的io,部署了io监控后,抓到每次都是kworker刷脏贡献了大吞吐量io,而脏页来源是某容器服务在不间断的往/var/log目录下写日志文件 +- 客户机器出现了iohang,部署了io监控之后,监控到了io夯住的位置,以及io下发的时间,最终与其他组件的日志比对,定位到了引发io夯的原因 \ No newline at end of file