- 内存超分
内存超分,是指分配给虚拟机的内存总和大于实际可用的物理内存总数。这样做的前提是,虚拟机操作系统里的内存不可能一直处于用满的状态。
但是,超分又不能过大,最好不要超过物理内存和 swap 的总和。否则,当所有客户机都处于较高内存使用率的情况下,会出现虚拟机因内存不足而被关机的情况。
内存超分的实现方式:内存交换(swapping)、气球(ballooning)、页共享(page sharing)。
- 内存交换(swapping)
使用交换空间来弥补内存不足,给虚拟机分配内存的时候,将物理机 swap 空间分配给虚拟机使用,这种方式性能要低一些。
- 页共享(page sharing)
通过 KSM(Kernel SamePage Merging)合并多个虚拟机进程使用的相同内存页,KSM 技术可以让内核在多个进程间共享完全相同的页。
KSM 让内核扫描正在运行的程序并比较它们的内存,如果发现内存页是完全相同的,就将它们合并成一个内存页,并标识 “写时复制”。如果有进程尝试去修改标识为 “写时复制” 的合并内存页,就为该进程复制出一个新的内存页来给其使用。
事实上,虚拟机运行相同的操作系统或者应用程序时,会存在大量完全相同的内存页。
- 气球(ballooning)
HostOS 内存不足了就会找 GuestOS 要内存来使用,通常情况下虚拟机需要先关机,调整内存配置之后再开机。
Ballooning 技术可以不对虚拟机关机就实现内存的调整,通过 ballooning 技术虚拟机释放空闲内存到虚拟机内的 “气球” 中,“气球” 中的内存可以供 Host 使用。
ballooning 是一种让内存超分的有效机制。例如:在一个为 8GB 的 Host 上,有 6 个内存为 2GB 的虚拟机(A、B、C、D、E、F),当在一段时间内 A,B,C 的负载很轻,就通过 ballooning 将其内存降到 512 M,这样 512M * 3 2G * 3 < 8G
。看起来 8G 内存,每个客户机分不到 2G 内存,实际上每个客户机可以使用到 2G 内存。
- 内存气球
当同一个物理机上的多个虚拟机之间出现内存竞争时,Hypervisor 将轮询物理主机上所有的虚拟机,通过内存气球驱动(virio_balloon)自动回收虚拟机中的空闲内存。内存气球驱动回收机制能够最大限度的提高内存资源的利用率。
内存气球位于虚拟机中,内存气球 “膨胀” 则是虚拟机将内存释放给宿主机,内存气球 “压缩” 则是宿主机将内存还给虚拟机。
- 当宿主机内存不足时
系统可以请求虚拟机回收已分配给它的部分内存,虚拟机会释放其空闲的内存。
假如客户机也内存不足,可能会导致其回收部分使用中的内存,这部分被回收的内存可能会被换出到客户机的交换分区 swap 中。
- 当客户机内存不足时
可以让宿主机的内存气球压缩,释放出内存气球中的部分内存让客户机使用。
Ballooning 价值:
- 内存调整无需重启虚拟机,内存的 ballooning(气球)技术可以在虚拟机运行时动态地调整它所占用的宿主机内存资源。
- 提升系统对内存的整体使用率,动态调整对内存的使用,可以避免有的地方需要内存的时候已经内存不足,实际很多已经分配出去给客户机使用的内存,客户机并未正在使用。
- 为内存超分提供了可行基础,内存超分的前提就是已分配给虚拟机的内存并没有被全部真正使用。
Ballooning 优点:
- 通过 ballooning 可以节约大量内存,因为可以控制和监控 ballooning 。虚拟机内存是通过 Balloon 命令调整的,所以可以监控系统内存并验证 ballooning 引起的变化。
- 通过 ballooning 可以精细的请求少量内存,也可以粗矿的请求大量内存。
Ballooning 缺点:
- 需要虚拟机操作系统加载 virtual_balloon 驱动,并非每个虚拟机都有该驱动,比如 Windows 就需要自己安装该驱动。
- 虚拟机内存被回收之后会影响虚拟机运行性能。
- 虚拟机中服务原来缓存到内存中的数据,因为内存不足而无法缓存,只能到存储中去读取,这样导致 IO 访问增加。
- 虚拟机中服务因为内存不足而异常。
- 缺乏自动化管理 ballooning 的机制,一般都是采用在 QEMU monitor 中执行 Balloon 命令来实现 ballooning 。
- 内存的动态增加或减少,会导致内存过度碎片化,从而降低内存使用的性能。
- 内存变化会影响虚拟机内核对内存使用的优化。比如:内核起初根据目前状态对内存的分配采取了某个策略,而突然由于 balloon 的效果让可用内存减少了很多,这时起初的内存策略可能就不是太优化的了。
KVM Ballooning 原理
- KVM Hypervisor 发送请求到虚拟机操作系统,命令虚拟机归还一定数量的内存给 Hypervisor。
- 客户机 OS 中的 virtio_balloon 驱动接收 Hypervisor 的请求,驱动后续动作的执行。
- virtio_balloon 使客户机的内存气球膨胀,气球中的内存不能被虚拟机访问,倒逼虚拟机进行内存回收。
- 如果虚拟机剩余可用内存不多,无法放内存气球膨胀到 Hypervisor 指定的大小,则气球膨胀只能尽力而为。
- 尽力而为的方式之一就是在可以的条件下,将内存置换到 swap 中。
- 客户机操作系统归还气球中的内存给 Hypervisor。
- Hypervisor 可以将从气球中得到的内存分配到任何需要的地方。
总结: 内存气球是一种内存超分技术,通过虚拟机中的 virtio_balloon 驱动调节虚拟机的可用内存,实现云计算平台中对虚拟机可用内存的动态分配控制。
内存气球膨胀,虚拟机可用内存减少,宿主机可用内存增加。
内存气球压缩,虚拟机可用内存增加,宿主机可用内存减少。