![如何在不禁用交换的情况下将重要的虚拟机保留在内存中?](https://linux22.com/image/622938/%E5%A6%82%E4%BD%95%E5%9C%A8%E4%B8%8D%E7%A6%81%E7%94%A8%E4%BA%A4%E6%8D%A2%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E5%B0%86%E9%87%8D%E8%A6%81%E7%9A%84%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%BF%9D%E7%95%99%E5%9C%A8%E5%86%85%E5%AD%98%E4%B8%AD%EF%BC%9F.png)
VM 主机 -> Xenon E5-2440,带 48G 内存...一切都运行 CentOS6.5 (2.6.32-431)
我有 4 个客户虚拟机,每个虚拟机的内存为 2G。它们的磁盘映像是本地文件。主机还运行着一个使用率不高的 NFS 服务器,但其他的就不多了。(swappiness=0)大约一天后,随着缓冲区缓存增长到近 40G,其中一些虚拟机几乎完全交换到磁盘。(查看方式:grep VmSwap /proc/PID/status)
我遇到的问题是,虽然这些虚拟机可能不经常使用,但它们必须随时待命。然而,实际上它们正在被替换,导致其响应时间出现严重问题。
我当然完全赞成让我的客户虚拟机使用合理大小的交换文件,并让操作系统决定缓冲区缓存和交换之间的平衡,但在我的用例中,这似乎对主机不起作用。
除了禁用主机上的交换之外,还有其他方法可以防止虚拟机响应能力下降吗?尝试使用 cgroups 还是直接拔掉交换文件?
答案1
您可以在 libvirt 的更高版本中将页面锁定到内存中:-
http://libvirt.org/formatdomain.html#elementsMemoryBacking
小心:使用 Fedora 19 作为虚拟机管理程序时不会出现这种情况,但是根据我能找到的最新 RPM 的更改日志,EL6.5 libvirt 存在这种情况;
- 2013 年 7 月 18 日星期四 Jiri Denemark - 0.10.2-21
- conf:避免 pmsuspended 域状态的 NULL 取消引用 (rhbz#822306)
- libvirt:定义域崩溃事件类型(rhbz#822306)
- qemu:重构 processWatchdogEvent(rhbz#822306)
- qemu:公开 qemuProcessShutdownOrReboot() (rhbz#822306)
- qemu:当客户机崩溃时实现“oncrash”事件(rhbz#822306)
- qemu:当客户机崩溃时实现“oncrash”核心转储事件(rhbz#822306)
- conf:修复解析 nat 端口 XML 节点时的内存泄漏(rhbz#851455)
- security_manager:修复比较(rhbz#984793)
- qemu:防止在没有客户代理配置的情况下 libvirtd 崩溃(rhbz#984821)
- qemu:修复 qemuAgentGetVCPUs() 中返回的 JSON 数组的双重释放问题(rhbz#984821)
- qemu_agent:添加对将数组附加到命令的支持(rhbz#924400)
- 添加对锁定域内存页面的支持(rhbz#947118)
- qemu:实现对锁定域内存页面的支持(rhbz#947118)
- qemu:检查 -realtime mlock=on|off 支持(rhbz#947118)
- qemu:将内存限制计算移至可重用函数(rhbz#947118)
- 实用程序:新的 virCommandSetMax(MemLock|Processes|Files)(rhbz#947118)
- qemu:当使用 memoryBacking/locked 时设置 RLIMIT_MEMLOCK (rhbz#947118)
- 添加 Gluster 协议作为支持的网络磁盘后端 (rhbz#849796)
- qemu:添加对基于 gluster 协议的网络存储后端的支持。(rhbz#849796)
- 测试:添加基于 gluster 协议的网络磁盘支持测试(rhbz#849796)
答案2
您可以使用 cgroups,并为每个 cgroup 设置 swappiness
http://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
http://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
KVM 虚拟 CPU 只是主机上的一个线程,因此可以像任何其他进程一样进行控制。
答案3
以下是 Matthew 解决方案的分步说明:
- 关闭虚拟机
virt-xml $VMNAME --edit --memorybacking locked=on
systemctl restart libvirtd
(不确定是否有必要)- 启动虚拟机
其中,$VMNAME
是虚拟机的名称。
我成功解决了之前我的虚拟机会被完全交换出去的情况。现在虚拟机的 qemu 进程的交换使用量为 0,并且响应迅速。
警告:根据libvirt 文档,qemu 的所有内存都将被锁定,它可能会不可预测地增长,并且应该设置一个hard_limit
来保护主机系统(如有必要,VM 将被杀死以保持在限制范围内)。