腾讯云CVM磁盘IO异常升高?3步排查与优化实战

2026-08-04 18:00:20

腾讯云CVM磁盘IO异常升高?3步排查与优化实战

一条简单的 ls 命令开始卡顿,Web 页面迟迟吐不出数据,监控平台却显示 CPU 与内存用量平平——这类诡异故障十有八九指向磁盘 IO 瓶颈。在腾讯云 CVM 上,当 IOPS 或吞吐量撞上云盘规格上限时,iowait 不会说谎,但真正致命的是队列不断堆积、服务响应断崖式下跌。快速完成 CVM磁盘IO异常排查与优化,需要从症状识别到关键指标交叉验证,再过渡到云平台独有视角,才能把根因钉在准确一层。

一、磁盘IO异常的影响与表现

1. IO高负载的典型症状

高负载最先冲击的是延迟敏感链路——API 响应从十几毫秒飙升至数秒,页面出现“假死”式白屏,但 htop 显示 CPU 多数时间处于空闲或在 iowait 状态。数据库层面,慢查询数异常增多,InnoDB 日志写入阻塞导致线程池迅速耗尽,连锁推高连接数。日常日志刷盘同样被拖垮,应用线程因 fsync 未返回而挂起。这类故障在促销高峰期或凌晨批处理场景中极易触发,小容量云盘的 IOPS 瓶颈往往被严重低估。

2. 如何确认是IO瓶颈

仅凭 iowait 高就下结论是磁盘太慢是个常见陷阱。真正的瓶颈判定需要两个硬指标:iostat -x 1%util 持续接近 100%,且 avgqu-sz 持续超过磁盘数的 2~3 倍。如果 %util 低而 iowait 高,只是部分 CPU 在同步等待 IO,磁盘并未过载。配合 pidstat -d 1 锁定耗 IO 进程,再通过 strace 或应用日志分析读写模式(大量 4K 随机写 vs 1M 顺序写),才能确认是否触及云盘性能极限。

3. 腾讯云CVM特有指标关注

操作系统内工具能揭示主机侧状态,但要区分“应用自身 IO 设计缺陷”与“云盘规格撞墙”,必须拉取云厂商侧数据。腾讯云 CVM 的云监控直接提供磁盘读写 IOPS、吞吐量及读写延时曲线,这些指标可与 OS 层的 iostat 结果交叉比对。比如云监控显示延时陡增且 IOPS 贴近云盘标称上限,同时实例内 %util 接近 100%,即可确认是底层云盘性能瓶颈,避免在应用调优上空耗时间。

二、快速定位IO问题的工具

处理磁盘IO异常时,最常见的误区就是先入为主地升级硬件或盲目调整内核参数。更科学的路径是从“观测工具链”入手,用数据把问题层级收敛到系统→进程→应用模式。接下来的三个工具分别对应不同深度,组合使用可以在几分钟内锁定元凶,而不是在iowait与慢查询之间反复横跳。

1. iostat —— 确认扣动扳机的是不是磁盘

很多人看到 top 里的 %iowait 超过 30% 就认定磁盘过载,但这是个经典误判——高 iowait 可能只是因为部分 CPU 核心在空闲等待 IO 完成,实际磁盘并未满负荷。真正决定磁盘是否饱和的指标是 %util(磁盘繁忙程度)和 avgqu-sz(平均请求队列长度)。

操作说明
在疑似故障的 CVM 上执行:

iostat -x 1 2

-x 输出扩展统计,1 2 表示采样 1 秒共 2 次,取第二次的值避免初始偏差。

效果说明与解读
如果输出中某块盘的 %util 持续超过 95%,且 avgqu-sz 长时间高于磁盘数的 2~3 倍(比如单块云盘该值 > 3),说明队列堆积严重,磁盘已成为瓶颈。此时看 r/sw/s 的总和,如果接近实例或云盘规格的 IOPS 上限(例如普通云盘约数百 IOPS,SSD 云盘数千至数万不等),性能撞墙就基本坐实。
在过去的一次促销期间案例中,CVM 的 avgqu-sz 飙到 128,%util 顶在 100%,但 iowait 只有 35%,CPU 仍在大量处理非 IO 任务——这恰恰说明磁盘极限已到,而不是 CPU 闲着。

值得留意的是,云厂商的云盘性能与容量强关联,小容量磁盘的 IOPS 和吞吐可能远低于你看过的宣传数字。与其靠经验估算,不如直接对比 iostat 读出的实际读写速度和云监控中的“磁盘 IOPS / 吞吐量”曲线,避免在 OS 层和平台层之间“各说各话”。

2. iotop —— 找出哪个进程在“肇事”(慎重)

当磁盘确认过载后,下一步是抓到乱写乱读的进程。iotop 可以像 top 一样实时展示进程 IO 开销,但它基于内核任务统计,高负载场景下自己可能消耗大量 CPU 并加剧 IO 压力——线上紧急情况直接全量跑 iotop 容易让系统雪上加霜。

操作说明
如果决定使用,请务必加上过滤参数:

iotop -oP

-o 仅显示有 IO 活动的进程,-P 显示线程级 IO,减少输出量。对于 4.18 以上内核,也可以用 --only 进一步限定。

效果说明
该命令会列出进程的磁盘读写速度和 IO 时间占比,能立刻看到是 MySQL、Java 应用还是 rsyslog 在拼命写盘。但根据经验,更推荐先用下面这个轻量级方法做初筛,iotop 仅作为交叉验证的最后手段。

3. pidstat —— 轻量级进程 IO 画像

在大多数生产环境,pidstat 是最推荐的一线进程级 IO 工具。它对系统开销极小,可以安全地加到定时监控脚本里,且输出直接包含进程 PID、读写速率和 IOWAIT 状态。

操作说明
每秒采集一次进程 IO 数据:

pidstat -d 1

输出示例:

08:15:23      UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
08:15:24      999      3201      0.00    4560.00      0.00  java
08:15:24      999      4022      0.00    1024.00      0.00  mysqld

效果说明
通过 kB_wr/s 很容易定位到写入狂魔进程。如果某 Java 应用的写入速率长期高于 20 MB/s,且结合 lsof -p PID 发现目标文件是日志或数据库文件,就可以立即转入针对性分析:例如 strace -f -p PID -e trace=write -o io.log 抓取写模式,或用 filefrag 检查碎片情况。
在云上实践时,我们常把 pidstat -d 1 2 放入 cron 每 5 分钟执行一次,当 kB_wr/s + kB_rd/s 超过预设阈值时触发云监控自定义告警,并附上当时的高 IO 进程快照。这样能将“事后救火”转为提前感知,这也是为什么推荐先用 pidstat,而不是直接冒险上 iotop

三招之间遵循“系统瓶颈 → 进程嫌疑 → 应用模式”的递进逻辑。先用 iostat 确认磁盘是否真的累了,再用 pidstat 揪出谁在制造压力,最后结合 strace 或应用日志分析 IO 行为。这比摸着黑调内核参数要有效得多。

三、磁盘IO异常的常见原因

把云盘性能不足简单归咎于“磁盘太慢”,往往会掩盖真正的凶手。在我们经手的大量线上案例中,磁盘IO异常升高极少是单一故障点,更多是文件系统、应用代码与云盘规格三者叠加后的压力释放。理解这些典型诱因的工作机制,比直接执行排查命令更重要——它决定了你会先看iostat的哪一列,以及能多快找到根因。

1. 文件系统缓存不足:被忽视的系统瓶颈

多数人对磁盘的直觉是“读写慢就是硬件差”,但 Linux 内核在文件系统和块设备之间还有一层庞大的页缓存(Page Cache)。当可用内存被应用挤压、缓存被迫收缩时,原本在内存中就能命中的热数据会退化为磁盘 IO,最极端的表现是:CPU 使用率不高、内存看似充裕,iowait 却持续在 20% 以上。

问题的机制在于脏页(Dirty Pages)的回收节奏。内核通过dirty_background_ratio(默认 10%)和dirty_ratio(默认 20%)来控制脏页比例。一旦脏页达到后台刷写阈值,内核启动回写线程;若比例继续攀升触达dirty_ratio,所有产生脏页的进程都会被强制同步等待写盘完成,此时磁盘 IO 会瞬间被打满,%util 直接顶到 100%,而应用看到的只是偶发性的“卡一下”。某金融客户在一次压力测试中遭遇了这种典型场景:TPS 稳定 8000 时,每 20 秒就出现一次 3~5 秒的服务停顿,iostat -x 1 显示 avgqu-sz 从 0.5 暴涨到 12,而吞吐量并未触碰云盘上限。根本原因是dirty_background_ratiodirty_ratio被运维无意中调成了 50%/60%,大量脏页在内存堆积,触发同步回写时写 IO 呈雪崩状态。

这种异常无法靠升级云盘解决,需要从内核参数入手:将vm.dirty_background_ratio降至 5,vm.dirty_ratio设为 10,并适当调小vm.dirty_expire_centisecs(如 3000,即 30 秒),让回写更平滑。同时可用grep -E "Dirty|Writeback" /proc/meminfo实时观察脏页大小,验证调优效果。文件系统挂载选项noatimerelatime也能减少元数据写入,对高 IO 场景收益明显。

2. 应用程序读写异常:那些“不该发生”的 IO

如果说内核参数是地基,应用程序的 IO 模式就是地基上的建筑。多数导致磁盘 IO 异常升高的应用问题,都源于两种不当设计:一是频繁的、无必要的同步写入;二是未根据云盘特性调整数据库或中间件的行为。

日志同步写是最常见的陷阱。很多开发者习惯用logging.FileHandler默认配置,每次写入一条日志都调用flush()fsync(),这使得毫秒级的业务操作频繁触发磁盘同步写,在日志量稍大时就能把 IOPS 打满。我们曾看到某广告推荐系统在一次算法更新后,API 响应时间从 50ms 恶化到 1200ms,CPU 和内存都很健康,最终通过strace -f -p-e trace=fsync发现,一个新增的埋点模块在每条请求路径上执行了三次 fsync。将日志改为异步落盘并设置缓冲区后,压力立刻消失。

数据库的 IO 异常更为隐蔽。MySQL InnoDB 引擎中,innodb_flush_method若设置为fdatasync,会同时使用 OS 缓存和 InnoDB 自己的缓冲池,产生双重缓存和额外的写放大;而O_DIRECT可绕过 OS 缓存,对 SSD 云盘通常更友好。innodb_io_capacity参数也常被忽略:它告知 InnoDB 可用的 IO 能力,若留为默认 200,而实际云盘能提供 5000 IOPS,后台刷脏页的速度就会受限,导致检查点时 IO 飙升。根据腾讯云云监控显示的磁盘最大 IOPS 动态调整该值(如 SSD 云硬盘设为 2000~3000),能显著平滑写入曲线。另一个高频问题是 Redis 的 RDB 持久化:bgsave触发时,fork 出的子进程会全量写入内存快照,若磁盘吞吐量不足,不仅 fork 耗时增加,还会阻塞主进程。这时候用sar -d 1观察到的写吞吐量会异常平坦——因为云盘吞吐上限已被顶满。

3. 磁盘类型与性能限制:云盘的“天花板”比想象中低

即使文件系统与应用都表现正常,云盘本身的规格限制也可能成为瓶颈,且这一层信息不透明程度最高。所有的云服务商(包括腾讯云)都为不同磁盘类型预设了 IOPS 和吞吐量上限,并且这些上限与磁盘容量严格绑定。一块 50GB 的普通云硬盘,性能可能只有基线 500 IOPS / 30MB/s;而不了解此约束的用户,会将应用迁移到云上后直接遭遇“性能墙”。

真正的难点在于,云盘性能瓶颈不像 OS 层面那样直观。%util 持续接近 100% 时,需要立刻到控制台查看云监控中的“磁盘读/写 IOPS”、“磁盘读/写吞吐量”、“磁盘读/写延时”等指标。如果云监控显示 IOPS 长时间达到或接近该磁盘类型的上限值,而 OS 内看到的吞吐量远未到理论带宽,说明是小 IO 随机读写将 IOPS 资源耗尽——此时即便扩容内存也无法改善,必须考虑换盘。某游戏服务器在运营活动期间,排行榜查询响应从 20ms 飙到 500ms,OS 层面iostat显示读 IOPS 仅 1200,工程师一度认为磁盘远未饱和。但核查云监控发现,那批服务器用的是 100GB 普通云硬盘,读 IOPS 上限恰是 1200。将磁盘在线扩容至 500GB(性能随容量线性提升)后,读 IOPS 上限达到 3000,问题即刻缓解。

对于突发性压力,云盘类型的灵活切换也是一种成本可控的手段。如果只是每晚跑批时段 IO 紧张,可以临时挂载一块高性能 SSD 云盘作为数据目录,任务结束后卸载,用fio --name=test --filename=/dev/vdb --size=1G --rw=randread --bs=4k --iodepth=64 --runtime=30 --time_based这类命令校验性能,投入产出远高于永久升级。关键是先通过监控确认“触顶”的事实,再选择合适的弹性策略,而不是盲目投入更高规格。

四、腾讯云CVM磁盘IO优化方案

排查做到这里,如果你已经能准确定位到问题进程,或者确认是云盘性能触顶,下一步就是动手优化。多数人这一步容易踩的坑是:上来就换盘。云厂商的极速型SSD当然能解决问题,但如果没有先消除应用层和内核层的“无效IO”,成本上去了,根子还在。下面两个优化方向,按成本从低到高、见效从快到慢的顺序来。

1. 调整内核参数:驯服Linux写回风暴

这是最容易被忽视、但见效最快的一步。Linux的脏页(dirty page)机制有个特点:平时看着IO很平稳,但一旦脏页比例突破dirty_ratiodirty_background_ratio阈值,内核会强制启动大规模回写,瞬间把磁盘IOPS打满。这就是为什么很多业务会表现出“间歇性IO飙升”,监控曲线呈脉冲状。

典型场景:你的应用批量写日志或导入数据,内存够大,脏页一直攒着,等到dirty_background_ratio(默认10%)触发,后台回写开始,但如果写入速度超过回写速度,脏页比例继续飙到dirty_ratio(默认30%),此时所有写操作都会被阻塞,直到脏页降下来。这一阻塞,你的API响应延迟可能从50毫秒直接飞到3秒。

操作方式:核心思路是“更早、更平滑地回写”,而不是等到水位告急再集中处理。通过sysctl调整四个关键参数:

# 降低触发后台回写的脏页比例(默认10%,改为5%)
vm.dirty_background_ratio = 5

# 降低强制阻塞写操作的脏页比例(默认30%,改为10%)
vm.dirty_ratio = 10

# 缩短脏页存活时间,超过300厘秒(3秒)就回写,避免积压
vm.dirty_expire_centisecs = 300

# 提高回写线程唤醒频率,从默认500厘秒缩短到100厘秒
vm.dirty_writeback_centisecs = 100

配置写入/etc/sysctl.conf后执行sysctl -p生效。效果是脏页会被更频繁、但每次量更小地刷新到磁盘,从监控上看IOPS曲线会从“脉冲波”变成“平缓丘陵”,峰值大幅降低。这会略微增加平均IO量——因为你更频繁地在写了——但换来的是对业务延迟的稳定可控,这个交换在大多数场景下是值得的。

一个提醒:网上有些教程会教你echo 3 > /proc/sys/vm/drop_caches来快速释放缓存,这条命令确实能瞬间清空脏页,但它也会强制丢弃所有文件系统缓存,执行瞬间业务IO会雪崩,严禁在线上环境使用,仅适合在测试环境验证脏页是否为问题源。

2. 应用层分离与缓冲:砍掉不必要的同步写

内核参数调完后,如果IO压力还在高位,就该动应用了。我们接触的案例里,应用层最大两个IO杀手是:日志同步写和数据库的双重缓存刷盘。

日志写优化:很多开发习惯在代码里每条日志都fsync()——这相当于每写一行“INFO: user login”,就强制磁盘完成一次物理写入。1000条日志就是1000次IO,而一行日志可能才100字节,磁盘的吞吐量连零头都用不上,IOPS先被打爆。解决办法有两个层次:轻量级的,检查日志框架配置,改为异步写(比如Logback的AsyncAppender或Python logging的QueueHandler),把多条日志聚合后批量写入;更彻底的,如果日志量巨大且对可靠性要求不是极高,可以直接上缓冲消息队列(比如用syslog协议转发到远端,或本地写文件时加上O_DSYNC以外的挂载选项,比如noatime,nodiratime)。

检查一下你的挂载选项:mount | grep " / ",如果能看到sync,且不是数据库专用目录,基本就是配置隐患。

数据库参数调优:MySQL/Percona系数据库最常见的问题写在innodb_flush_log_at_trx_commitinnodb_flush_method上。如果innodb_flush_method没有设置成O_DIRECT,数据写盘时会经过操作系统页缓存和InnoDB缓冲池的双重缓存,同一份数据被写了两次,IO量翻倍。而innodb_flush_log_at_trx_commit=1(每次事务提交都刷新redo log)和sync_binlog=1(每次事务提交都同步binlog),在高并发写场景下会导致redo日志和binlog的写入成为绝对瓶颈。

这不是让你一刀切改成=0而是需要根据业务对数据丢失的容忍度来权衡:如果能接受几秒钟内的数据丢失(比如批量数据处理、会话状态更新),可以设为=2,把刷新频率从“每次事务”变成“每秒一次”,磁盘的写请求峰值能下降一个数量级。同时,将innodb_io_capacity调至云硬盘实际IOPS上限的60-70%,让InnoDB知道磁盘的真实能力,避免它自己的后台刷脏页过于激进。腾讯云控制台里“磁盘IOPS”监控曲线和innodb_io_capacity在不在一个量级,对一下就能看出有无配置错误。

五、实战案例:一次IO高排查

一家电商SaaS服务商的技术团队在2024年黑五前夕遭遇了一次典型的磁盘IO故障。当天下午3点,业务监控突然告警:商品详情页API响应时间从日常的120ms飙升至4.7秒,订单创建接口超时率突破12%。运维人员第一反应是看CPU和内存——两者使用率均在40%以下,无明显异常。这一度让团队陷入排查僵局。

关键时刻,top命令的输出给了线索:CPU iowait指标高达78%,而系统态和用户态CPU占用都很低。这说明CPU不是在计算,而是在“等磁盘”。

1. 问题现象与初步分析

登录服务器后,团队执行的第一个命令是:

iostat -x 1 3

输出结果触目惊心:系统盘vda%util持续在99.8%-100%之间波动,平均队列长度avgqu-sz达到47.3——这台机器只挂载了一块云盘,理论队列深度不应该超过2-3倍磁盘数,47意味着大量IO请求在排队等待处理。

更关键的数据是读写模式。iostat显示每秒写请求数w/s超过3800,而读请求r/s仅为120。这不是正常的混合负载,而是典型的“写入风暴”。写入吞吐量达到128MB/s,恰好触及了该规格CVM实例的云盘性能上限(该实例挂载的是100GB普通云硬盘,IOPS限制约4000,吞吐量限制约130MB/s)。

初步判断:某个进程在疯狂写磁盘,直接打满了云盘性能墙。

下一步要定位“谁在写”。团队用了两个命令交叉验证:

# 轻量级方法:用pidstat看进程级IO
pidstat -d 1 5

# 结果明确指向两个进程:
# PID 28471 (java) - 每秒写操作超过2000次
# PID 9123  (mysqld) - 每秒写操作约800次

Java进程的IO量远超数据库,这是反常的。通常数据库才是IO大户,但这次主犯是应用本身。

2. 排查流程与关键命令

锁定Java进程后,需要确定它到底在写什么文件、以什么模式写。这里用了一个组合:

# 查看进程打开的文件描述符
lsof -p 28471 | grep -E "\.log|\.data" | wc -l
# 输出:147个文件描述符,其中大量指向 /data/logs/ 目录

# 实时追踪系统调用,观察写入行为
strace -f -p 28471 -e trace=write,fsync,fdatasync -c
# 统计持续30秒后Ctrl+C退出

strace统计结果揭示了两大问题:

第一,日志同步写。应用框架的日志配置使用了immediateFlush=true(类似Log4j2的配置),导致每条业务日志都调用一次fsync强制刷盘。统计显示30秒内发生了2.8万次fsync调用,平均每次耗时3.7毫秒——单次很快,但累积效应惊人。

第二,数据库参数不当。MySQL的innodb_flush_log_at_trx_commit=1(每次事务提交都刷盘),配合黑五前的商品缓存预热脚本(每批插入200条记录立即commit),导致大量小事务高频刷写redo log。

同时,检查内核脏页参数发现:

sysctl vm.dirty_ratio vm.dirty_background_ratio
# vm.dirty_ratio = 20
# vm.dirty_background_ratio = 10

这台机器内存32GB,脏页比例达到10%(3.2GB)时后台回写启动,20%(6.4GB)时强制阻塞写入。配合应用的高频小IO,系统周期性出现“脏页洪水”——大量积压的脏页集中回写,瞬间打满磁盘。

综合判断:这不是单一故障,而是应用同步写、数据库参数、内核脏页策略三个因素叠加,最终被云盘性能上限放大的复合型问题。

3. 优化措施与效果验证

团队分三步执行优化,每步都做了效果验证。

第一步:应用层日志异步化(立即生效)

修改日志框架配置,将immediateFlush改为false,并启用缓冲区:


同时调整业务代码,将非关键路径的日志打印从同步改为写入内存队列、由独立线程批量刷盘。

改造后iostat观察5分钟:w/s从3800降至900,%util从99.8%降至32%,效果立竿见影。

第二步:内核脏页参数调优

修改/etc/sysctl.conf

vm.dirty_background_ratio = 3
vm.dirty_ratio = 5
vm.dirty_expire_centisecs = 500
vm.dirty_writeback_centisecs = 100

执行sysctl -p生效。这组参数的含义是:脏页占内存3%时启动后台回写(更早触发,避免堆积),5%时阻塞写入(降低封顶水位),同时脏页老化时间从30秒缩短到5秒,回写周期从5秒缩短到1秒——让写入更平滑,而非“要么不写、要么写爆”。

第三步:数据库参数优化

临时调整MySQL参数(非停机调整,通过在线修改):

SET GLOBAL innodb_flush_log_at_trx_commit = 2;
-- 从每次提交刷盘改为每秒刷盘一次,性能提升明显
-- 代价是极端宕机时可能丢失1秒内的已提交事务

同时将预热脚本改为每1000条记录一次事务提交,减少fsync频率。


最终效果验证

优化完成后,业务高峰期再次压测。iostat -x 1显示%util稳定在45%-65%之间,avgqu-sz降至1.2。商品详情页API响应恢复至130ms,订单创建超时率降至0.3%以下。云监控曲线显示,优化前磁盘写延时峰值达87ms,优化后稳定在2-5ms。

值得注意的是,这次优化并未升级磁盘类型或扩容——问题根源在软件层,解决也应在软件层。如果直接换极速型SSD云硬盘,性能天花板从130MB/s提升到350MB/s,短期可能掩盖问题,但应用仍会无意义地刷盘数万次,徒增成本且持续劣化。先改代码、再调参数、最后才考虑换硬件——这是成本最低且效果最持久的路径。

六、预防与监控体系建立

解决眼前的 IO 飙高只是第一步,避免在凌晨三点被告警电话叫醒,依赖的是一套能真实反映云盘工作状态的预防与监控组合。这一节给出三条可立刻落地的策略。

1. 设置 IO 监控告警

多数团队只在服务器宕机或 CPU 打满时才收到通知,磁盘 IO 的告警往往处于“盲区”。实际上,腾讯云 CVM 控制台的云监控模块已经提供了“磁盘 IOPS”“磁盘吞吐量”“磁盘读写延时”等原生指标,不需要在操作系统里额外折腾。

操作步骤
1. 进入云监控 > 告警策略,针对“云服务器-磁盘监控”类型创建新策略。
2. 选择指标:对于数据库或日志盘,建议同时监控“磁盘写 IOPS”和“磁盘读/写延时”。延时比 IOPS 更能直接反映用户体验——云盘突发流量下,IOPS 可能尚未触及规格上限,但 IO 等待时间已经让慢查询铺满监控屏。
3. 设置阈值:不要在满载的 100% 才告警。以“磁盘写 IOPS”为例,当 5 分钟内持续达到该云盘规格的 80% 即触发告警;延时指标可设置 >50ms 作为警告线。
4. 告警通道:绑定企业微信、短信或电话告警,并配置阶梯通知——第一级发给运维群,30 分钟未处理上升至值班经理。

效果说明
某电商团队曾将“磁盘写延时”告警从默认关闭改为 >30ms 即通知,在一次夜间索引重建任务意外打满普通云盘的写入带宽时,收到告警后在线将磁盘升级为增强型 SSD,避免了下单接口的连锁超时。

除了云监控,也可以在操作系统层布置一道兜底告警。下面的脚本每 5 分钟采集一次 iostat,当 %util 或 avgqu-sz 超过阈值时,触发自定义事件上报到云监控。

#!/bin/bash
# 采集并行等待队列和利用率
STATS=$(iostat -x 1 2 | tail -n +3 | grep -E '^[a-z]' | awk '{print $1,$14,$16}')
while read -r DEV UTIL AVGQ; do
    if (( $(echo "$UTIL > 95" | bc -l) )) || (( $(echo "$AVGQ > 5" | bc -l) )); then
        # 上报自定义事件,示例使用腾讯云 put-monitor-data 接口
        /usr/local/bin/put-monitor-data --namespace "Custom/IO" \
          --metric "HighIOUtil" --dev "$DEV" --value "$UTIL"
    fi
done <<< "$STATS"

注意:云盘类型不同,性能上限相差悬殊。一块 50GB 的普通云盘约有 1000 IOPS,而同等容量的极速型 SSD 可达 12000 IOPS。告警阈值必须和当前实例、磁盘规格匹配,否则小规格磁盘一使用就告警,产生大量噪音。

2. 定期性能基线评估

任何优化决策都离不开基线。“看起来 IO 很高”和“比上周同期高了 3 倍”是完全不同的故事。建立基线的方法并不复杂,核心是持续采集并定期对比。

操作步骤
1. 选择业务低峰期(如凌晨 3 点-5 点)和高峰期(如 20 点-22 点)两个时段,用 iostat -x 1 10 采集 IO 指标,重点记录 avgqu-sz、%util、r_await、w_await
2. 将数据存入时序数据库或简单的 CSV 文件,按月生成最大、平均、P95 曲线。
3. 版本上线或大促前,同样做一次短时压力测试,将测试期间的 IO 数据与现有基线对比,预判是否需要扩容或变更磁盘类型。

效果说明
一个内容分发团队在高峰期发现 CPU iowait 升至 40%,但云监控显示云盘 %util 仅 60% 左右。对比历史基线后,发现问题出在应用层在某个修改后引入了过多 O_SYNC 标记的打开文件操作,内核脏页刷写被频繁触发,而非云盘能力不足。事后他们直接在 CI 流程中加入了一个简单的 IO 模式检查,防止代码回归引入不必要的同步写。

基线的另一个价值在于:在进行磁盘类型选型或容量规划时,能以数据说服成本决策者。例如,当基线上反映出“每天 23 点索引重建时,磁盘写吞吐量逼近规格极限的 90%”,便可将升级 SSD 云盘的提议与直接业务损失风险挂钩,避免因宕机倒逼的被动改造。

3. 云监控自定义指标与自动化巡检

官方提供的 IOPS、吞吐量指标侧重“外在表现”,而 avgqu-sz、%util、脏页比例等 OS 层指标能揭示 IO 堆积的真实原因。腾讯云云监控支持自定义指标上报,你可以将这些与磁盘相关的关键参数一并纳入同一监控视窗,构建“应用-OS-云盘”三级监控体系。

操作步骤
1. 在内核参数层面启用 dirty_ratio 监控。通过 /proc/meminfo 获取 DirtyWriteback 字段,计算脏页比例,超过 dirty_background_ratio(默认 10%)时主动抛出指标。
2. 写一个轻量采集脚本,每 60 秒执行一次,将 /proc/meminfo 的脏页值、iostatavgqu-sz%util 组装为 JSON,调用云监控的 PutMonitorData API 或使用自带 Agent 的上报通道。
3. 在云监控控制台合并显示:自带磁盘指标与自定义指标放在同一 Dashboard,设置组合告警(如“%util>90% 且 avgqu-sz>3 持续 3 分钟”)。
4. 对于临时性的 IO 压力任务,采用预挂载高性能数据盘的方式。在脚本中检测到待执行任务时,自动通过云 API 创建一块增强型 SSD 并挂载,任务结束后卸载、删除,避免长期持有高成本资源。

效果说明
某日志分析平台在巡检脚本中集成了此类自定义指标,成功预警了一次磁盘性能雪崩。当时,%util 尚未达到 100%,但 avgqu-sz 已从日常的 0.5 飙升至 12,表明大量写请求在排队。团队提前将部分日志流切换到对象存储,避免了线上查询服务中断。这种“组合条件触发”的告警机制,比单一指标提前了约 15 分钟预警,为人工介入留出了窗口。

综合来看,预防体系不追求大而全,关键在于:告警覆盖真实痛点、基线提供决策依据、自定义指标打通 OS 与云端的视角断层。当这三部分稳定运行后,面对 CVM 磁盘 IO 异常升高,你不再是拿着 top 茫然的分析师,而是有一份实时健康扫描和深度排查路径图的掌控者。

联系人:罗先生

582059487 15026612550
立即咨询

QQ

QQ:582059487 点击复制添加QQ好友

电话

15026612550
7*24小时服务热线

微信

二维码扫一扫添加微信
TOP
微信咨询二维码
微信咨询 获取代理价(更低折扣)
更低报价 更低折扣 代金券申请
咨询热线:15026612550