我如何排查导致 Swap 与高 CPU 的 KVM 内存问题(Runbook + 实际案例)

发布: (2026年2月24日 GMT+8 15:36)
7 分钟阅读
原文: Dev.to

抱歉,我需要您提供要翻译的具体文本内容(文章正文),才能为您进行简体中文翻译。请粘贴或上传您想要翻译的文本,我会在保持原有格式和技术术语的前提下完成翻译。

最近,我在一台 KVM 虚拟化服务器上发现了异常

服务器并未处于高负载状态,但之前我看到:

  • qemu-system-x86 占用 800 %+ CPU
  • kswapd 运行异常热
  • Swap 使用率接近 100 %

随后:

  • CPU 负载下降
  • RAM 仍有大量空闲
  • Swap 仍然满载

下面是我完整的排查流程——你也可以照此操作。

🧠 环境概况

  • 虚拟化平台: KVM + libvirt
  • 宿主机内存: 314 GB
  • Swap: 976 MB
  • 运行多个 VM
  • 出现问题的 VM: testnet-node3

🔍 步骤 1 – 确认高 CPU 进程

ps -eo pid,comm,%cpu,%mem --sort=-%cpu | head -n 10

输出(摘录)

qemu-system-x86  818%

说明: 在 Linux 中,100 % 代表 1 个 CPU 核心,所以 800 % 约等于 8 核心满载。某个 VM 正在大量占用 CPU。

🔎 步骤 2 – 将 PID 对应到具体 VM

每个 VM 都以 qemu-system-x86 进程运行。

ps -fp <PID>          # 查看该 PID 的完整命令行
virsh list --all      # 列出所有 VM
virsh dominfo <VM>    # 查看指定 VM 的详细信息

通过上述命令,我确认导致问题的 VM 为 testnet-node3

📊 步骤 3 – 检查宿主机内存与 Swap

free -h
Mem:   314Gi total
       217Gi used
        94Gi free
Swap:   976Mi total
        963Mi used

Swap 已经 98 % 被占用,而 RAM 仍有 94 GB 空闲——这常常会让人惊慌。

🧪 步骤 4 – 验证是否存在活跃的内存压力

vmstat 1 5

关注以下列:

含义
si页面 换入(swap in)
so页面 换出(swap out)

如果两者均为 0,说明系统 没有 处于活跃的内存压力中。

我的输出

si = 0
so = 0

解释:
Swap 的占用是历史遗留的;内核之前曾因内存压力换出页面,但当前已经没有压力,这属于正常现象。

🔥 为什么 Swap 在有空闲 RAM 时仍然保持满载

Linux 不会 自动把已换出的页面重新加载回 RAM,除非真的需要。一次内存压力事件可能导致 Swap 长时间保持满载,即使之后 RAM 已经空闲——这属于正常行为。

🧠 步骤 5 – 检查 VM 的内存分配

virsh dominfo testnet-node3
Max memory: 98304000 KiB

98304000 KiB ≈ 94 GB → 该 VM 分配了约 94 GB 内存。

❓ 这台 VM 真正出现内存不足吗?

在 Guest 内部检查:

free -h
vmstat 1 5

如果 Guest 显示:

  • 使用了 Swap
  • 出现 OOM‑killer 信息
  • 内存使用率 > 90 %

则增加 RAM 是合理的。否则,高 CPU 可能是工作负载导致,而非内存短缺。

🚀 步骤 6 – 安全地增大 VM 内存

先停止该 VM,目标内存 128 GB

# 128 GB 转换为 KiB
128 * 1024 * 1024 = 134217728 KiB
virsh setmaxmem testnet-node3 128G --config
virsh setmem    testnet-node3 128G --config

验证:

virsh dominfo testnet-node3

启动 VM:

virsh start testnet-node3

📊 步骤 7 – 验证调整后宿主机的稳定性

free -h
Mem:   314Gi total
       221Gi used
        89Gi free
Swap:   0B used

Swap 已被清空。

vmstat 1 5

si = 0, so = 0, CPU 空闲率高 → 系统健康。

🧩 根本原因模式

  1. VM 工作负载突增 → Guest 消耗大量内存
  2. 宿主机出现内存压力 → Swap 被填满,kswapd CPU 飙升
  3. qemu 进程显示高 CPU(由 Guest 驱动)
  4. 工作负载恢复后,Swap 仍保持满载(因为没有活跃压力)

如果不查看 vmstat,很多人会误判问题。

🛑 常见误区

  • ❌ 在未检查 Guest 使用情况的前提下直接增加宿主机 RAM
  • ❌ 认为 Swap 100 % 使用就意味着系统要“挂掉”
  • ❌ 忽视 vmstat 输出
  • ❌ 将宿主机全部内存都分配给 VM

📐 KVM 宿主机容量规划建议

  • 对于大内存宿主机(如 314 GB),预留 16–32 GB 给宿主操作系统。
  • 切勿把 100 % RAM 分配给 Guest。
  • 定期监控 Swap;对大内存机器而言,1–4 GB 的 Swap 已足够。

e‑RAM 系统。

🧠 专业技巧

# 列出所有虚拟机的总内存分配
virsh list --name | while read vm; do
  virsh dominfo "$vm" | grep -i memory
done
# 查看是否启用了交换
vmstat 1
# 找出消耗内存最多的进程
ps -eo pid,comm,%mem,%cpu --sort=-%mem | head

🎯 最终要点

仅仅使用交换并不等同于内存问题。

真正问题的关键指示器包括:

  • 活跃的 swap 进/出vmstat
  • 主机或客机日志中的 OOM 事件
  • kswapd 持续的高 CPU 使用率
  • 客机层面的内存压力

在我的案例中,虚拟机的内存分配已经足够;高 CPU 是工作负载导致的,残留的 swap 只是过去一次压力事件的遗留。

内存升级摘要

从 94 GB → 128 GB 扩容

  • 主机保持健康
  • 没有 swap 压力
  • 系统稳定

如果您在生产环境中运行 KVM,了解内存 + swap + CPU 的交互至关重要。

盲目添加 RAM 很容易。

正确诊断才是让您成为优秀系统工程师的关键。

0 浏览
Back to Blog

相关文章

阅读更多 »

没人想负责的 Systemd Bug

TL;DR:存在一个命名空间 bug,影响 Ubuntu 20.04、22.04 和 24.04 服务器,导致随机服务故障。自 2021 年起已在系统中报告……