内存不浪费
先量出来的
我们没有先挑方法,先量。一台跑着 17 台虚拟机、共 44 GB 虚拟机内存的宿主,开机一天后,49% 的虚拟机内存是零页,其中 35% 是整块 2 MiB 全零。现代内核会把释放的页清零,而虚拟机开机后大部分内存根本没碰过。
零页有个好处:没有内容要保存。不用压缩、不用换出到盘、虚拟机里不用装驱动;要还回去时,给一块新的零就行。
怎么做的
- 一个低优先级线程每 5 分钟按 2 MiB 一块扫一遍虚拟机内存,连续两轮都是零的块,从虚拟机里拆掉映射。
- 虚拟机再碰到这一块时,马上映射回去。
- 收回来的块组成宿主 ZFS 池的一块 L2ARC 缓存盘。虚拟机要回某一块时,宿主等它上面的缓存 I/O 做完,清零(约 0.1 毫秒),再映射回去。ZFS 对每次 L2ARC 读取都核对校验和,被要回去的块只意味着多读一次盘。
内存在账面上仍是那台虚拟机的,不借给别的虚拟机,所以不超售,也永远不会出现要不回来的情况。
实测
- 开发机上 7 小时:回收 14.9 GB,占虚拟机内存的 34%;被要回的约 5%。
- 真机上的正确性:虚拟机写入零和随机数据,等两轮扫描后读回校验,中间还经历一次宿主重启,每个字节都对。
- 宿主上的随机读测试(ARC 4 GB):没有借来的缓存时 10.7k IOPS,借到 6 GB 后 16.7k IOPS。
限制
- 不超售。要不要把回收的内存拿去多开虚拟机,等攒几个星期真实的"被要回"数据再说。
- 带直通设备的虚拟机不参与回收,因为设备会直接往它的内存里写。
- 虚拟机的盘在高速 NVMe 上、ARC 命中率本来就高时,收益很小;它的主场是机械盘上的存储池。直通控制器后面的盘不经过宿主的缓存。
- 只被读、没被写的块本可以共享一页零,不用真的收回,还没做。
- 相关参数在装好的系统上都能调,网页上的设置页还没做。