标题中的存储虚拟化,涉及到两个方面,分别是内存和磁盘的虚拟化技术。内存的虚拟化就不得不提EPT和VPID 技术.
首先申明下本人其实不想写一些纯理论的东西,但是架不住面试经被问,为此特将一些特别复杂的技术底层都隐去,尽量将技术讲的简单,我个人信奉一句话'If you can't explain it simply, you don't understand it well enough.'
内存虚拟化发展
初心:想拥有一段从头开始的地址段。
- 在物理机中内存空间是一个从零开始的连续的物理内存空间,为了使虚拟机也拥有一个从零开始的连续的物理内存空间,KVM 引入了一层新的地址空间,即客户机的物理地址空间。(该地址空间并不是真正硬件上地址空间)。这样原先在物理机上一个单层架构变成现在三层架构。
- 客户机虚拟地址(Guest Virtual Address,GVA )
- 客户机物理地址(Guest Physical Address,GPA )
- 宿主机物理地址 (Host Physical Address,HPA )
得到一个三节棍
一次内存的访问要经过两次地址转换 GVA -> GPA -> HPA ,其效率可想而知是不高的。为了解决上述问题,一种叫影子页表(Shadow Page Tables)技术从软件上实现了客户机虚拟地址 -> 宿主机的物理地址的直接转换。
影子魔法
-
影子页面虽然解决了两次地址转换的问题,但是其为每一个客户机都维护一个影子页表,其内存开销也比较大,而且其技术基于软件来实现,维护和调试都比较复杂。
-
为了解决影子页表的问题,Intel的CPU提供了EPT技术(AMD提供的类似技术叫作NPT,即Nested Page Tables),直接在硬件上支持GVA→GPA→HPA的两次地址转换,从而降低内存虚拟化实现的复杂度,也进一步提升了内存虚拟化的性能.
-
而 VPID(Virtual Page Identifier)则是 EPT 技术中一个重要的标识符。它用于区分不同虚拟机之间的页表,确保每个虚拟机都有独立的页表和内存空间。
-
VPID 在虚拟化环境中起到类似身份证的作用。每个虚拟机都被分配一个唯一的 VPID,用于标识该虚拟机的页表。这样,不同的虚拟机可以同时运行,并且每个虚拟机都有自己独立的内存空间,互相之间不会干扰彼此。
总结来说,EPT 是一种虚拟化技术,用于用硬件的方式来实现两次地址转换,改善虚拟机内存访问效率,而 VPID 则是在 EPT 技术中使用的标识符,用于区分不同虚拟机的页表和内存空间。
验证
- CPU 标记中是否支持EPT 和VPID
lscpu |grep -E "ept |vpid" 或
cat /proc/cpuinfo |grep -E "ept |vpid"
- 模块是否加载
在默认情况下,如果硬件支持了EPT、VPID,则kvm_intel模块加载时默认开启EPT和VPID特性,这样KVM会默认使用它们
# cat /sys/module/kvm_intel/parameters/ept
Y
# cat /sys/module/kvm_intel/parameters/vpid
Y
如果发现自己的环境没有开启可以通过
modprobe kvm_intel ept=1,vpid=1
来开启
扩展
内存也是可以超配的(也称为过载使用over-commit),只是我们一般不这样做,但是有些测试环境可以采用一些技术来允许内存的超配使用。
当计算机的内存不足时,宿主机操作系统可以采用一些技术来帮助解决这个问题。以下是三种常见的技术:
1)内存交换(swapping):这是一种利用硬盘上的交换空间来暂时存储不常用的内存数据的方法。当内存不足时,操作系统会将一部分数据从内存中移出,并存储到硬盘上的交换空间中。这样,操作系统可以腾出更多的内存供其他程序使用。当需要访问被交换出去的数据时,它们将被再次加载回内存。
概括:将内存中数据,挤掉不常用数据放在硬盘上来释放内存空间。对应就是linux上Swap 分区。
2)气球(ballooning):这是一种在虚拟化环境中使用的技术。它通过在客户机和宿主机之间协作来管理内存。当宿主机的内存资源紧张时,它会使用一个特殊的驱动程序,即virio_balloon驱动,在客户机中释放一些未使用的内存。这些被释放的内存可以供其他需要的客户机使用。
概括:物理机内存不足时,膨胀客户机内存气球,挤压出空闲内存供物理机使用,同理客户机内存不足时,压缩内存气球,释放出内存供客户机使用。
kvm虚拟机加上如下配置
在客户机里面进行验证
3)页共享(page sharing):当多个进程在客户机上运行时,它们可能会使用相同的内存页,例如代码或库文件。为了节省内存空间,操作系统可以使用KSM(Kernel Samepage Merging)技术将这些相同的内存页合并为一个,并让多个进程共享该页。这样,操作系统可以减少内存的使用,提高资源利用率。
缺点:利用 KSM 使内存超用。这会导致消耗一定的计算资源用于内存扫描,加重了 CPU 的消耗。内存超用,使得频繁地使用 swap 交互,导致 VM 性能下降。
概括:在有多个客户机使用相同的操作系统时,其会存在大量相同的内存页,将这些内存页合并,进而来减少内存占用。但其频繁的内存扫描,加重CPU的消耗,本质上是一种以CPU换内存的措施,生产中是建议关闭。
- 禁止所有客户虚拟机KSM 页共享:
echo 0 > /sys/kernel/mm/ksm/pages_shared
echo 0 > /sys/kernel/mm/ksm/pages_sharing
内存优化技术
大页内存:
大页内存是计算机系统中的一种内存管理机制,它将传统的小块内存(通常为4KB)组合成更大的内存块(通常为2MB或1GB)。相比于小页内存,大页内存拥有更大的连续地址空间。
大页内存的主要作用是改善系统的性能。这是因为在传统的小页内存中,每个页面都需要额外的内存开销来存储页表信息。当系统处理大量的内存访问请求时,这些额外的开销会导致缓存不命中、TLB(Translation Lookaside Buffer)失效等问题,从而降低系统的性能。
通过使用大页内存,系统可以减少页表的数量和大小,从而降低了内存管理的开销。这样一来,系统在处理内存访问时可以更高效地利用缓存和TLB,提高数据访问速度,减少对内存子系统的负载。特别是在需要大量连续内存的应用程序(如数据库、虚拟化环境等)中,使用大页内存可以显著提升性能。
总而言之,大页内存通过将小块内存组合成更大的内存块,减少了内存管理的开销,提高了系统的性能,尤其适用于对连续内存需求较大的应用场景。
- 4.1 查看是否开启了大页内存。
cat /sys/kernel/mm/transparent_hugepage/enabled
- 4.2 如果没有开启则编辑开机启动菜单,开启大页内存
编辑 /etc/default/grub
#加上如下参数,这里是开启了大页内存,大小为1G的大页内存,有2页,则大页内存的总容量=1G*2
transparent_hugepage=always hugepagesz=1G hugepages=2
这里先简单介绍下大页内存的加载,之后我们在DPDK的章节将会详细介绍大页内存的使用。