
当数据中心的一台 Ubuntu 22.04 香港服务器www.a5idc.com出现 磁盘 I/O 持续高负载 时,很容易影响业务性能(如 MySQL 延迟、NFS 挂载卡顿、容器写盘阻塞等)。本文结合我在跨境电商平台运维中的实际案例,讲述如何使用 iotop 、systemd 工具链 等定位根因,并给出优化方案与评估数据。
一、问题背景与现象描述
凌晨,A5数据的监控系统告警:
- iowait CPU 时间持续在 30% 以上
- 关键业务响应时间突然变长
- SSD 磁盘队列深度异常增长
在排查指标时,我们注意到:
| 指标名称 | 当前值 | 正常阈值 |
|---|---|---|
| iowait % | ~32% | < 5% |
| avgqu-sz | ~15 | < 5 |
| await (ms) | ~40 | < 20 |
| svctm (ms) | ~8 | < 5 |
这些指标均由
iostat -x 5输出采集。
二、现场服务器硬件与环境参数
在分析前,我们先列出受影响香港服务器的硬件配置,以便后续定位:
| 项目 | 规格/型号 |
|---|---|
| 机型 | Dell PowerEdge R650 |
| CPU | Intel Xeon Silver 4310 (12核心/24线程) |
| 内存 | 128GB DDR4 ECC |
| 操作系统 | Ubuntu 22.04.4 LTS (内核 5.15) |
| 磁盘 | 2× NVMe SSD (Samsung PM9A3 3.84TB, RAID1) |
| 文件系统 | XFS |
| 关键服务 | MySQL 8.0, Docker 容器, systemd 管理 |
三、诊断工具与思路
我们主要依赖以下工具:
| 工具 | 作用 |
|---|---|
iotop |
监控实时 I/O 行为 |
systemd-cgtop |
查看 cgroup(服务/容器)I/O 使用 |
systemd-analyze blame |
评估启动阶段耗时(与 I/O 相关服务) |
iostat |
长周期统计磁盘性能指标 |
strace |
跟踪进程系统调用(非必选,用于深度定位) |
四、步骤详解:如何使用 iotop 定位 I/O 顶流进程
1)安装与运行 iotop
bash
sudo apt update
sudo apt install -y iotop
运行:
bash
sudo iotop -o -b -t 5 > /tmp/iotop.log &
参数说明:
-o:仅显示正在进行 I/O 的进程-b:批处理模式(适合日志分析)-t:时间戳输出
输出类似:
2025-01-02 09:15:10
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
12345 be/4 mysql 0.00 B/s 30.2 M/s 0.00 % 15.20 % mysqld
23456 be/4 root 0.00 B/s 8.4 M/s 0.00 % 4.10 % docker-containerd
...
五、结合 systemd 工具链判断服务级别 I/O 压力
1)使用 systemd-cgtop 观察单位服务行为
bash
sudo systemd-cgtop -b -n 5
输出主要关注 IO% 列:
CGROUP TASKS %CPU %MEM IO
/ 112 9.1 35.2 18.3
/system.slice/mysqld.service 28 3.8 12.7 13.9
/system.slice/docker.service 45 2.6 10.1 4.2
...
从这个输出,我们可以明确定位到 mysqld.service 对磁盘 I/O 贡献最大。
2)分析 systemd 启动阶段 I/O 延迟
虽然不是故障根因,但了解启动 I/O 冲突也有帮助:
bash
systemd-analyze blame | head -n 10
若某个服务启动耗时过长,也可能反映 I/O 相关瓶颈。
六、真实案例分析:mysqld 磁盘写放大
通过 iotop 和 systemd-cgtop 我们确认 mysqld 是 I/O 主因,但进一步观察发现:
- 写入主要集中在 binlog 和 InnoDB redo log
- 磁盘延迟(await)波动明显
1)Redistribute 写负载
我们在 MySQL 中启用了 Group Commit 与 innodb_flush_log_at_trx_commit=2(牺牲一部分持久性换取性能):
sql
SET GLOBAL innodb_flush_log_at_trx_commit=2;
SET GLOBAL sync_binlog=100;
这样可以减少每次事务提交对磁盘的强制刷写,提高整体吞吐。
七、优化方案与执行
方案一:调整 IO 调度器
Ubuntu 22.04 默认使用 mq-deadline。对 NVMe SSD 可尝试 none 以减少 CPU 调度开销:
bash
for d in /sys/block/nvme*; do
echo none | sudo tee $d/queue/scheduler
done
持久化:
bash
cat <<EOF | sudo tee /etc/udev/rules.d/60-ioschedulers.rules
ACTION=="add|change", KERNEL=="nvme*", ATTR{queue/scheduler}="none"
EOF
方案二:限制容器 I/O
如果 Docker 容器占用严重,可设置 cgroup 限制:
bash
docker run -d \
--name webapp \
--device-write-bps /dev/nvme0n1:50mb \
--device-read-bps /dev/nvme0n1:50mb \
your-image
方案三:升级硬件队列深度
bash
sudo nvme get-feature /dev/nvme0n1 -f 7 -H
若队列深度小于 1024,可视负载提升队列设置。
八、优化前后评估数据
以下为调整前后部分关键指标对比:
| 指标 | 优化前 | 优化后 |
|---|---|---|
| avgqu-sz | 14.8 | 4.2 |
| iowait % | 31.7 | 8.5 |
| await (ms) | 39.6 | 19.3 |
| mysqld IO% | ~13.9 | ~7.1 |
| 容器总体 I/O | ~22.5% | ~10.4% |
九、注意事项与最佳实践
- 监控告警要覆盖 I/O 延迟:例如 await > 20ms 时触发。
- 生产环境调参需逐步验证:每次调整后至少观察 30 分钟以上。
- 避免与备份窗口重叠:定时备份造成瞬时 I/O 峰值。
十、结语
通过 iotop 和 systemd 工具链,我们能快速定位磁盘 I/O 高负载的罪魁祸首,并从服务层、调度器层到容器层多角度优化。在 Ubuntu 22.04 的服务器上,这样的组合是故障排查的利器。希望本文的步骤、表格和实战建议,能帮助你在类似的运维场景中快速解决问题。