磁盘I/O很高的解决思路

当遇到磁盘I/O突然升高时,运维人员可通过监控工具分析历史记录,定位造成读写频繁的程序。文章以xen虚拟机为例,通过iostat输出展示设备的IO状态,发现100%利用率的设备,并进一步分析可能的原因,包括数据操作、备份、慢查询和RAID卡问题。解决思路涉及检查进程、优化SQL、排查硬件故障。

介绍

磁盘IO突然很高是运维人员经常碰到的问题,这是由于有大量的磁盘读和写造成的,通常发生在数据库身上,然而发生的场景各种各样。本文举几个例子阐述解决思路。

 

正文

找到是什么程序在大量的进行读写操作。可以通过监控软件(如zabbix)或工具(如atop)查看磁盘IO的历史记录。

本文假设场景发生在xen虚拟机上,在母机上用iostat查看IO状态

# iostat -xdk 2

输出如下:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util

sda               0.00    24.50    0.00   13.50     0.00   141.00    20.89     1.71  126.67    0.00  126.67  39.70  53.60

sdb               0.00     1.50    0.00   12.00     0.00   132.00    22.00     1.42  108.33    0.00  108.33  83.33 100.00

dm-0              0.00     0.00    0.00   12.50     0.00    12.50     2.00     2.36  188.48    0.00  188.48  11.84  14.80

dm-1              0.00     0.00    0

<think>嗯,用户需要排查服务器磁盘I/O使用率达到100%的问题。这是一个典型的运维故障场景,需要系统性地分析。用户身份可能是开发或运维人员,从引用内容看可能对Linux系统不太熟悉,但具备基本命令行操作能力。 用户的核心需求很明确:获取可操作的排查步骤和解决方案。深层需求可能是希望快速恢复服务,同时避免数据丢失风险。从引用[1][3]看用户可能遇到过存储空间不足的问题,这次转向I/O性能瓶颈,说明ta的运维场景涉及多种存储类故障。 先梳理排查逻辑:I/O 100%意味着磁盘成为系统瓶颈,常见于并发写入、大数据查询或硬件故障。需要分三步走:确认现象、定位进程、分析行为。引用[2]提到TPS不但I/O满载的情况值得注意,可能是特殊场景。 具体工具选择上: - 全局监控用iostat最直观,能看await/util等关键指标 - 进程级用iotop/pidstat,比top更精准 - 文件级用lsof+strace组合,引用[3]的日志文件案例很典型 - 特殊场景要考虑page cache,引用[2]的dentry堆积问题 解决方案需要区分临时处置和根治措施。临时方案如限流或进程重启要谨慎,特别是数据库类应用。根治方案要结合业务场景,比如日志轮转、查询优化等。用户引用[3]提到的rm删除空间不释放问题也要纳入注意事项。 最后考虑生成相关问题。用户显然在系统运维领域持续遇到挑战,可以延伸I/O调度算法、云存储优化等方向。不过首次回复先聚焦基础排查,避免信息过载。</think>好的,排查服务器磁盘I/O使用率达到100%是一个常见的性能问题,会导致系统响应缓慢甚至无响应。以下是详细的排查步骤和解决方案思路: **核心思路:** 找到导致 I/O 的源头(哪个进程?在读写哪些文件?读写模式是什么?),然后针对性地解决。 **排查步骤:1. 确认 I/O 瓶颈** * **`iostat` (来自 sysstat 包):** 这是最核心的工具。执行命令: ```bash iostat -dx 1 5 ``` * `-d`: 显示磁盘统计信息。 * `-x`: 显示扩展统计信息(关键!)。 * `1`: 每秒刷新一次。 * `5`: 显示 5 次。 * **关键指标解读:** * **`%util`:** **这就是磁盘 I/O 使用率**。接近或达到 100% 确认存在瓶颈。 * **`await`:** 平均每次 I/O 请求的等待时间(毫秒)。值越,I/O 队列越长,延迟越大。通常 `await` 显著升伴随 `%util` 100%。 * **`r/s`, `w/s`:** 每秒的读、写请求次数。 * **`rkB/s`, `wkB/s`:** 每秒读、写的数据量(KB)。 * **`avgqu-sz`:** 平均 I/O 队列长度。大于 1 通常表示设备饱和。 * **`svctm`:** 平均每次 I/O 请求的服务时间(毫秒)。现代磁盘通常在 10ms 以下。 * **重点关注哪个磁盘设备(如 `sda`, `vdb`)的 `%util` 达到 100%。** **2. 定位 I/O 进程** * **`iotop`:** 最直观的工具(需要 root 权限)。执行: ```bash iotop -oP ``` * `-o`: 仅显示正在进行 I/O 的进程。 * `-P`: 仅显示进程(不显示线程)。按 `O` 键可以切换排序方式(如按 I/O 百分比)。 * **查看 `IO>` 或 `DISK READ`, `DISK WRITE` 列,找出占用率最的进程 (PID 和 命令)。** * **`pidstat` (来自 sysstat 包):** 提供更详细的进程级 I/O 统计。执行: ```bash pidstat -d 1 ``` * `-d`: 报告 I/O 统计。 * `1`: 每秒报告一次。 * **查看 `kB_rd/s`, `kB_wr/s`, `kB_ccwr/s` 列,找出读写量大的进程 (PID 和 命令)。** * **`top` / `htop`:** 虽然不如前两个专业,但也能提供线索: * 在 `top` 中按 `Shift + I` 切换 I/O 模式(显示 `%wa` - 等待 I/O 的 CPU 时间百分比)。 * 在 `htop` 中,按 `F2` -> `Columns` -> 添加 `IO_READ_RATE` 和 `IO_WRITE_RATE` 列。 **3. 分析进程行为 (针对步骤 2 找到的 I/O PID)** * **`lsof`:** 查看进程打开了哪些文件(包括正在读写的)。 ```bash lsof -p <PID> ``` * 查找 `REG` 类型(常规文件)且 SIZE/OFF 列显示数字在变化的文件,这些很可能就是 I/O 源头文件。 * **`strace` / `ltrace` (谨慎使用):** 跟踪进程的系统调用或库函数调用,能看到具体的文件读写操作 (`read`, `write`, `open` 等)。在负载下使用可能加剧问题。 ```bash strace -p <PID> -e trace=open,read,write,close ``` * **结合文件路径:** 分析步骤 3a 找到的文件路径: * 是日志文件吗?(如应用日志、数据库日志) * 是数据库文件吗?(如 MySQL 的 ibdata1, ib_logfile*, .ibd 文件) * 是临时文件吗? * 是应用程序的数据文件吗? **4. 检查文件系统和缓存 (辅助分析)** * **`free -h` 或 `cat /proc/meminfo`:** 查看内存使用,特别是 `buffers` 和 `cached` 的大小。Linux 会利用空闲内存缓存磁盘数据。如果缓存很大,说明系统在积极利用缓存,但 I/O 可能意味着缓存命中率低或数据无法被缓存(如大量随机写)。 * **`vmstat 1`:** 查看系统整体状态: * `b` 列:等待 I/O 的进程数(大于 0 且持续存在说明有阻塞)。 * `si`, `so` 列:每秒从交换区读入/写入的内存量 (KB)。如果非零,说明发生了交换,会极大拖慢 I/O。 * **`dmesg | grep -i error` 或 `journalctl -p 3 -b`:** 查看内核日志和系统日志,是否有磁盘错误、文件系统错误、驱动问题等记录。 **5. 分析读写模式 (根据步骤 1, 2, 3 的信息)** * **是读密集型还是写密集型?** (看 `iostat` 的 `rkB/s` vs `wkB/s`,`pidstat`/`iotop` 的进程读写比例)。 * **是顺序读写还是随机读写?** 随机读写(尤其是小 I/O)对磁盘性能挑战更大。数据库操作、大量小文件访问通常是随机的。大文件传输、日志追加通常是顺序的。 * **是哪个应用程序?** 数据库?Web 服务器?备份任务?大数据处理?日志收集器?自定义应用? **解决方案思路 (根据排查结果针对性处理):** 1. **优化应用程序/服务 (最常见):** * **调整日志级别和轮转策略:** 减少不必要的详细日志输出。确保日志文件能及时轮转(如使用 `logrotate`)并**正确清理旧日志**(参考引用[3],避免仅用 `rm` 删除被打开的文件导致空间未释放,应使用 `truncate` 或 `echo > file` 或重启服务)。 * **优化数据库:** * 检查慢查询日志,优化低效 SQL。 * 检查索引是否合理。 * 调整 `innodb_io_capacity`, `innodb_flush_method` (MySQL InnoDB) 等与 I/O 相关的参数。 * 考虑分离数据和日志到不同物理磁盘。 * 评估是否使用了过多临时表或磁盘排序。 * **优化备份策略:** 避免在业务峰进行全量备份。考虑增量备份或快照。确保备份任务不会耗尽磁盘 I/O。 * **优化代码逻辑:** 减少不必要的磁盘 I/O(如频繁读写小文件、未使用缓存)。批量处理读写操作。 2. **调整内核/文件系统参数 (需谨慎):** * **调整 I/O 调度器:** 不同的调度器(`cfq`, `deadline`, `noop`, `kyber`, `mq-deadline`)对不同的负载(顺序/随机)有优化。例如,数据库常推荐 `deadline` 或 `noop` (对于 SSD)。 * 查看当前调度器:`cat /sys/block/<device>/queue/scheduler` * 临时修改:`echo deadline > /sys/block/<device>/queue/scheduler` * 永久修改需修改 `/etc/default/grub` 或使用 udev 规则。 * **调整虚拟内存参数:** 如 `vm.dirty_ratio`, `vm.dirty_background_ratio`。这些参数控制脏页(被修改但未写回磁盘的内存页)的比例。增大它们可以允许更多脏页累积,减少写 I/O 次数(但增加数据丢失风险)。**调整需非常谨慎,理解其含义。** * **调整文件系统挂载选项:** 如 `noatime`/`relatime` (减少访问时间更新带来的写操作),`data=writeback` (ext4, 提性能但增加风险) 等。 3. **资源隔离与限制:** * **`ionice`:** 在启动可能占用 I/O 的进程(如备份)时,使用 `ionice` 降低其 I/O 优先级。 ```bash ionice -c2 -n7 /path/to/command # 设置空闲级别(最低优先级) ``` * **`cgroups` (cgroups v1 I/O 子系统 或 cgroups v2 `io` 控制器):** 更强大的方式,可以限制特定进程组(cgroup)的磁盘带宽或 IOPS(每秒 I/O 操作数)。适用于容器环境或需要严格隔离的场景。 4. **检查硬件和底层存储:** * **使用 `smartctl` (来自 smartmontools 包) 检查磁盘健康状态:** ```bash smartctl -a /dev/<device> # 如 /dev/sda ``` * 查看 `SMART Attributes` 和 `SMART Error Log`,关注 `Reallocated_Sector_Ct`, `Current_Pending_Sector`, `Uncorrectable_Error_Cnt` 等关键属性值是否异常或阈值被触发。磁盘故障会导致 I/O 重试和性能骤降。 * **检查 RAID 状态:** 如果使用 RAID,检查是否有磁盘掉线或降级 (`cat /proc/mdstat`, `megacli` 等工具)。 * **评估存储性能:** 使用 `fio` 工具进行基准测试,了解磁盘的真实性能(顺序/随机,读/写,不同 I/O 大小和队列深度下的 IOPS 和带宽),对比当前负载是否超出其能力。 * **考虑升级硬件:** * 用 SSD 替换 HDD:这是解决随机 I/O 瓶颈最有效的方法。 * 增加磁盘数量:通过 RAID 0/10 或直接分离数据到不同物理盘来提并行 I/O 能力。 * 增加内存:更大的内存意味着更大的磁盘缓存,能减少实际物理 I/O 次数。 5. **处理特定问题:** * **交换 (Swap) 导致 I/O:** 如果 `vmstat` 显示 `si`/`so` 非零,说明物理内存不足,系统在频繁使用交换空间。**根本解决方法是增加物理内存或优化应用程序内存使用。** 临时措施是降低 `vm.swappiness` 值 (如 `sysctl vm.swappiness=10`),但这只是让系统更不愿意使用 swap,不能解决内存不足的本质。 * **文件系统缓存问题:** 如引用[2]提到的 `dentry`/`inode` 缓存占用过多内存 (`slabtop` 查看),可能由海量小文件引起。重启能临时解决,但需优化应用或调整内核参数 (`vfs_cache_pressure`)。极情况可能需要定期清理缓存(`sync; echo 3 > /proc/sys/vm/drop_caches`,**生产环境慎用,仅用于诊断,会清除所有缓存导致后续 I/O 陡增**)。 **总结流程:** 1. `iostat -dx 1 5` -> 确认 `%util` 100% 的设备。 2. `iotop -oP` 或 `pidstat -d 1` -> 定位 I/O 进程 (PID)。 3. `lsof -p <PID>` -> 查看该进程正在读写哪些文件。 4. 分析文件类型、路径和应用程序行为 -> 确定根本原因(日志?数据库?备份?应用问题?硬件?)。 5. 针对原因实施解决方案 -> 优化应用/配置、调整参数、限制资源、检查硬件、升级硬件。 **关键提示:** * **备份数据:** 在进行任何可能影响数据的操作(尤其是修改内核参数、文件系统操作)前,务必备份重要数据。 * **理解风险:** 调整内核参数或文件系统选项可能带来稳定性风险或数据丢失风险,务必在测试环境验证并充分理解其含义。 * **监控:** 部署监控系统(如 Prometheus + Grafana + node_exporter)持续跟踪磁盘 I/O、内存、CPU 等关键指标,便于及时发现和预警问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值