背景
我们在 Ubuntu 16.04 上运行了几个 KVM 服务器,并已开始测试升级到 20.04。我们发现,尽管我们从未在 16.04 服务器上看到任何交换使用情况,但几天后,20.04 服务器将显示几百 MB 的交换使用情况。这不是一个大问题,因为 vmstat 显示的交换活动很少,而 munin graphs 确认交换输入/输出微不足道,但我们仍然想了解这种行为。
到目前为止,我们已经使用 Nagios 来监控交换使用情况,并在发现任何交换使用情况时发出警报。从 16.04 升级到 20.04 的系统正在运行 5 个负载较轻的虚拟机。主机系统显示已使用的内存约为 29G,总内存约为 200GB。没有峰值或任何导致内存使用率如此之高的情况。虚拟机的内存使用受到限制,并且 KVM 服务器本身上没有运行其他占用大量内存的进程。
root@kvm-xx:~# free -m
total used free shared buff/cache available
Mem: 193336 29495 768 5 163072 162404
Swap: 6675 240 6435
顶部,进程交换的示例:
PID VIRT RES SHR S %MEM COMMAND SWAP
6447 18,2g 15,8g 22908 S 8,4 qemu-system-x86 239352
6160 2661052 1,9g 21880 S 1,0 qemu-system-x86 90788
6315 2129436 644388 21856 S 0,3 qemu-system-x86 29724
6391 10,4g 7,9g 22832 S 4,2 qemu-system-x86 24028
6197 6505584 3,0g 23008 S 1,6 qemu-system-x86 10972
5686 9908 2944 2720 S 0,0 cron 60
5805 24404 14440 4388 S 0,0 munin-node 4
vmstat 的典型输出,显示交换输入/输出没有变化。
root@kvm-xx:~# vmstat 2 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 407620 869916 214784 165081536 0 0 270 12 5 2 0 2 98 0 0
2 0 407620 869900 214784 165081536 0 0 0 28 8533 24140 0 2 98 0 0
1 0 407620 869836 214784 165081536 0 0 0 28 8642 24682 0 2 98 0 0
该系统在 16.04 上运行了一年,使用相同的 VM 和负载,没有交换。
已经尝试和测试过的内容
升级后发现未安装 numad,并且 VM 未固定到同一物理 CPU 上的 vcpu。这意味着跨 numa 节点的内存使用情况。安装了 numad 并验证了固定。我认为交换使用率更高前确实会改变,但还不能肯定地说。
预计此行为与内核有关,因此从 5.4 升级到 HWE 5.11 内核。5.4 和 5.11 上的行为相同。
尝试禁用 KSM(内核同页合并),因为我们不需要它,并消除它作为交换使用的可能来源。
尝试完全禁用交换,以查看是否存在实际的内存不足,此时 OOM-killer 会发挥作用。这种情况并没有发生,所以在我看来,交换似乎不是必需的,但出于某种原因仍在使用。
想法和思路
我相信由于某种原因,即使 swappiness = 0,内核也会决定将非活动页面换出以进行交换。这可能是随 20.04 附带的新内核而改变的行为。
理想情况下,我们希望内核只在最后手段下进行交换,就像以前的行为一样,并使用交换使用情况监控来检测交换的使用情况并发出 Nagios 警报。
我已经阅读了几个关于类似主题的帖子,但发现关于可能的解释存在矛盾的信息。
我真正想要避免的是,我们将一些负载较重的 16.04 服务器升级到 20.04,然后看到这个问题升级为生产中的实际问题。
我知道 swapoff / swapon 可以手动将内存移出交换区,但问题是它为什么要进行交换。
如果有人对此有所了解,将不胜感激。
谢谢!