玩转KVM: 内存balloon的奇妙
前言
上篇介绍了kvm的KSM内存合并技术,了解KSM的应用场景。下面进一步KVM的内存气球balloon。
KVM的balloon技术原理
balloon技术应用场景
下面总结了一下内存气球使用时候的情况:
Ballooning在节约内存和灵活分配内存方面有明显的优势,其好处有如下三点。
① 因为能够控制和监控ballooning,所以ballooning能够潜在地节约大量的内存。它不同于内存页共享技术(KSM是内核自发完成的、不可控),VM系统的内存只有在通过命令行调整balloon时才会随之改变,所以能够监控系统内存并验证ballooning引起的变化。
② Ballooning对内存的调节很灵活,既可以精细的请求少量内存,又可以粗犷的请求大量的内存。
③ hypervisor使用ballooning让VM归还部分内存,从而可以缓解其内存压力。而且从气球中回收的内存也不要求一定要被分配给另外某个进程(或另外的VM)。
从另一方面来说,KVM中ballooning的使用不方便、不完善的地方也是存在的,其缺点也有如下几个。
① Ballooning需要VM操作系统加载virtio_balloon驱动,然而并非每个VM系统都有该驱动(如windows需要自己安装该驱动)。
② 如果有大量内存从VM系统中回收,Ballooning可能会降低VM操作系统运行的性能。一方面,内存的减少,可能会让VM中作为磁盘数据缓存的内存被放到气球中,从而VM中的磁盘I/O访问会增加;另一方面,如果处理机制不够好,也可能让VM中正在运行的进程由于内存不足而执行失败。
③ 目前没有比较方便的、自动化的机制来管理ballooning,一般都是采用在QEMU monitor中执行balloon命令来实现ballooning的。没有对VM的有效监控,没有自动化的ballooning机制,这可能会让生产环境中实现大规模自动化部署并不很方便。
④ 内存的动态增加或减少,可能会使内存被过度碎片化,从而降低内存使用时的性能。另外,内存的变化会影响到VM内核对内存使用的优化,比如:内核起初根据目前状态对内存的分配采取了某个策略,而突然由于balloon的效果让可用内存减少了很多,这时起初的内存策略可能就不是太优化的了。
balloon技术实践
KVM中的Ballooning是通过宿主机和VM协同来实现的,在宿主机中应该使用2.6.27及以上版本的Linux内核(包括KVM模块),使用较新的qemu-kvm(如0.13版本以上),在VM中也使用2.6.27及以上内核且将“CONFIG_VIRTIO_BALLOON”配置为模块或编译到内核。在很多Linux发行版中都已经配置有“CONFIG_VIRTIO_BALLOON=m”,所以用较新的Linux作为VM系统,一般不需要额外配置virtio_balloon驱动,使用默认内核配置即可。
我在windows2008R2和centos7下面完成balloon的应用操作。
Centos7:
VM查看balloon状态:
在vm中,可以通过内核,模块加载,pci设备等查看balloon是否正常运行。
[root@kvm-guest~]# grep VIRTIO_BALLOON \ /boot/config-2.6.32-279.el6.x86_64
CONFIG_VIRTIO_BALLOON=m
[root@kvm-guest ~]# lsmod | grep virtio
virtio_balloon 4856 0
virtio_pci 7113 0
virtio_ring 7729 2 virtio_balloon,virtio_pci
virtio 4890 2 virtio_balloon,virtio_pci
[root@kvm-guest ~]# lspci -s 00:04.0 -v
00:04.0 Unclassified device [00ff]: Red Hat, Inc Virtio memory balloon
Subsystem: Red Hat, Inc Device 0005
Physical Slot: 4
Flags: fast devsel, IRQ 10
I/O ports at c100 [size=32]
Kernel driver in use: virtio-pci
Kernel modules: virtio_pci
根据上面输出可知,VM中virtio_balloon模块已经加载,有一个叫做“Red Hat, Inc Virtio memory balloon”的PCI设备,它使用了virtio_pci驱动。如果是WindowsVM,则可以在“设备管理器”看到使用VirtIO Balloon设备,稍后可以检验一下。
在宿主机查看并设置balloon:
我通过virsh工具,
virsh # qemu-monitor-command centos7.0 --hmp --cmd info balloon
balloon: actual=4096
virsh # dommemstat centos7.0
actual 4194304
last_update 1524110865
rss 2362284
设置balloon
virsh # qemu-monitor-command centos7.0 --hmp --cmd balloon 2046
virsh # dommemstat centos7.0
actual 2095104
last_update 1524110865
rss 2358728
或者
virsh # setmem centos7.0 2Gib # --size默认是Kib
actual 2097152
swap_in 0
swap_out 0
major_fault 245
minor_fault 154498
unused 3772824
available 3881744
rss 1034116
如果没有使用Balloon设备,则monitor中用“info balloon”命令查看会得到“Device 'balloon' has not been activated”的警告提示。而“balloon 2046”命令将VM内存设置为2046MB。
(4)设置了VM内存为512 MB后,再到VM中检查,如下所示。
[root@kvm-guest ~]# free -m
total used free shared buff/cache available
Mem: 1742 236 1224 0 281 1280
Swap: 2047 0 2047
如果是WindowsVM(如Win7),当balloon使其可用内存从2GB降低到512MB时,在其“任务管理器”中看到的内存总数依然是2GB,但是看到它的内存已使用量会增大1536MB(如从其原来使用量350MB,变为1886MB),这里占用的1536MB正是Balloon设备占用的,WindowsVM系统其他程序已不能使用这1636 MB内存,这时宿主机系统就可以再次分配这里的1536MB内存用于其他用途。
另外,值得注意的是,当通过“balloon”命令让VM内存增加时,其最大值不能超过QEMU命令行启动时设置的内存,例如:命令行中内存设置为2048MB,如果在Monitor中执行“balloon 4096”则设置的4096MB内存不会生效,其值将会被设置为启动命令行中的最大值(即2048MB)。