检查自己的 KVM 内存有没有被超售
KVM 内存超售的方法,一般而言就三种:
- 内存交换(Swap)
- 气球驱动(Balloon)
- 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 |
个人结论
我好像有一点洁癖,不允许我的内存被超售。




