为什么 Ubuntu 服务器 20.04 在 vm.swappiness = 0 的情况下仍然在有大量可用内存的地方进行交换?

为什么 Ubuntu 服务器 20.04 在 vm.swappiness = 0 的情况下仍然在有大量可用内存的地方进行交换?

背景

我们在 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 可以手动将内存移出交换区,但问题是它为什么要进行交换。

如果有人对此有所了解,将不胜感激。

谢谢!

相关内容