0%

检查自己的 KVM 内存有没有被超售

检查自己的 KVM 内存有没有被超售

KVM 内存超售的方法,一般而言就三种:

  1. 内存交换(Swap)
  2. 气球驱动(Balloon)
  3. KSM(Kernel Samepage Merging)

1. 内存交换(Swap)

当系统内存不够用时,宿主机会把部分长时间未操作(读写)的内存交换到磁盘上的 Swap 分区,等相关程序需要运行时再恢复到内存中。

说白了,就是宿主机把 Swap 当内存用。

2. 气球驱动(Balloon)

通过 virtio_balloon 驱动,可以动态调整 Guest 与 Host 的可用内存空间。Balloon 的工作原理,是在虚拟机中安装一个 kmod。当 KVM 宿主机内存不足时,会根据 virtio_balloon 判断哪些内存页面可以被回收,然后由 virtio_balloon 占用这些内存,并返回给宿主机使用。

说白了,就是小鸡里有一个“间谍” virtio_balloon。当 KVM 宿主机内存不足时,virtio_balloon kmod 会申请占用小鸡的空闲内存,占用后的这部分内存会释放回宿主机。

3. KSM(Kernel Samepage Merging)

KSM 是一种内存合并技术,它可以在 KVM 中实现内存共享,从而节省内存空间。它是 Linux Kernel 的一种内存共享机制,在 2.6.32 版本引入,用于合并具有相同内容的物理主存页面,以减少页面冗余。

在 Kernel 中,KSM 会定期扫描用户注册的内存区域。当发现有相同的页面时,就会将它们合并,并用一个添加到页表中的新页面来代替原来的页面。当页面需要修改时,再复制新的内存页做修改,也就是 copy-on-write

说白了,就是不同小鸡里相同的内存页面如果有重复,KVM 宿主机会把这些页面只保存一份。

各个方案的问题,以及如何发现内存被超售

宿主机加 Swap 当内存

这个方法是最蠢的,看一下 iowait 就能发现。

如果客户长期跑基于内存的应用,例如 memcached,还会导致 IO 爆表,也就是大家常说的“滥用内存”。

这种情况基本测试一下内存就能发现:如果内存读取速度低于 1 GB/s,那就很可疑了,毕竟 DDR3 ECC 都比这个快。

小鸡被加了气球驱动(Balloon)

先检查:

1
lsmod | grep virtio

看看有没有 virtio_balloon。如果有,可以直接rm:

1
rmmod virtio_balloon

这种方法对性能来说没有明显缺点,但问题是客户的 RAM 会莫名其妙少一大截。

KSM(Kernel Samepage Merging)合并内存页

这种方法正常来说没有什么明显缺点,但如果 KVM 宿主机的内存已经满了,当客户机(小鸡)想修改内存页时,就必须先复制新的内存页,再做修改,也就是 copy-on-write

如果这时内存不够,就可能触发 OOM Killer,导致进程直接崩溃。

如何检查 KSM 超售

进入目录:

1
cd /sys/kernel/mm/ksm

里面有几个关键文件:

  • run:是否开启 KSM。为 1 时表示开启,0 表示停止,2 表示正在强行停止 KSM 并取消合并所有合并页。
  • pages_shared:共享的物理页数。
  • pages_sharing:正在被共享的物理页数。

检查命令:

1
cat /sys/kernel/mm/ksm/run

个人结论

我好像有一点洁癖,不允许我的内存被超售。