NFV场景下KVM虚拟机的性能优化

时间:2024-04-01 22:22:21
NFV场景下网元运行在虚拟机中,而虚拟机之间的连接也由虚拟网络互连。由于CT网元,特别是数据面网元,对计算能力和转发能力要求非常高,网络虚拟化无论在技术上还是运维上都是一个系统化的演进优化过程。从技术上看,实现虚拟化由易到难的顺序是:控制面->业务面->媒体(数据)面,当前运营商的NFV化尝试主要集中在控制面网元。从运营商的角度看,VNF、EMS和VNFM主要是设备厂家的范畴,对应于传统的物理设备和厂家网管,而上层的NFVO+OSS以及底层的NFVI+VIM则属于运营商的公共平台,是整个ETSI NFV架构的基石。
NFV架构下的性能、可靠性等很大程度上依赖于NFVI+VIM,事实上就是OpenStack。目前主流的虚拟层是基于x86架构下的KVM方案,本文仅列举了NFV场景下KVM优化的相关知识点,不涉及网络拓扑、协议等层面的优化。
虚拟层主要包括计算、存储和网络,下面的优化也分别对应于这几部分。

NUMA亲和

在高性能服务器上,一般有多个槽(Socket)上可以插CPU,每个CPU有多个核(Core),而支持超线程的CPU,每个核有2个超线程(HT),也就是2个逻辑核。根据CPU访问内存中地址所需时间和距离,我们可以将CPU和内存结构分为SMP(Symmetric Multi-Processor,也称之为一致内存访问UMA)、NUMA(Non-Uniform Memory Access Architecture,非一致性内存访问)和MPP(Massive Parallel Processing,本文不涉及)。如图:
NFV场景下KVM虚拟机的性能优化

UMA方式即是传统的通过FSP访问北桥的内存方式,各个CPU和所有的内存的访问延迟是一致的。而NUMA将CPU和相近的内存配对组成节点(node),在每个NUMA节点里,CPU都有本地内存,访问距离短(也叫亲合性好),性能也相对好。

NFV场景下KVM虚拟机的性能优化

虚拟层应支持Guest OS的NUMA感知功能,也即VM中识别的NUMA拓扑(CPU、内存)应和虚拟层为其分配的资源的NUMA拓扑一致(比如:VM的2个vCPU是从NUMA0和NUMA1上分配的,在VM内部识别到的CPU也应分为2个NUMA)。

CPU核绑定

虚拟层需支持将vCPU绑定到物理CPU的逻辑核上。在某些应用场景下,出于性能、服务等级协议SLA保证等因素方面的考虑,VM需要绑定CPU核。CPU核绑定可以避免资源竞争,增加CPU缓存命中率。
NFV场景下KVM虚拟机的性能优化
通过在VM上设置CPU核绑定可以限制VM在哪个CPU上运行,但并不意味着这个CPU只服务于一台VM,除非其它VM也都进行了核绑定。核绑定适合于对cache依赖较大的应用,但对于设计高频率线程间通信的应用可能会有反作用。同时,OpenStack要求将核绑定和非绑定的应用分别建立不同的资源池,比如划分为不同AZ或者HA(Host Aggregate),这是由于非核绑定的应用仍旧会抢占核绑定的应用的CPU资源。

NUMA reclaim

zone_reclaim_mode模式是在2.6版本后期开始加入内核的一种模式,可以用来管理当一个内存区域(zone)内部的内存耗尽时,是从其内部进行内存回收还是可以从其他zone进行回收的选项。
NFV场景下KVM虚拟机的性能优化
不同的参数配置会在NUMA环境中对其他内存节点的内存使用产生不同的影响。默认情况下,zone_reclaim模式是关闭的,适合对内存cache的依赖要高于对内存速度依赖的场景,宁可让内存从其他zone申请使用,也不愿意清本地cache。如果确定应用场景是内存需求大于缓存,而且尽量要避免内存访问跨越NUMA节点造成的性能下降的话,则可以打开zone_reclaim模式,此时页分配器会优先回收当前不用的page cache页,然后再回收其他内存。

支持大页内存

在现代计算机体系结构和操作系统中,通常可以支持超过一种以上的内存页大小。在实际使用中,除了常态使用的4K Byte大小的内存页以外,还可以在系统中支持2MB、1GB等多种规格的内存大页。NFV虚拟层需支持内存大页技术,且默认需将划分给VM使用的全部内存配置为1GB大页,此时,单个VM可使用的内存大小为1GB的整数倍。
NFV场景下KVM虚拟机的性能优化
在计算机系统中使用内存大页特性的根本原因是,随着现代计算机系统中运行的应用所访问的内存范围不断扩大,现有的处理器中的TLB(Translation lookaside buffer,又称快表,一种高速缓存)条目数已经显得非常有限。这种情况可能导致TLB miss概率明显提升,进而导致应用访问内存性能下降,最终影响应用的整体性能。比如32G内存,TLB的可以容纳8~1024条记录,如果使用4K内存页,则需要8388608页,而使用1G内存大页则只要32页。这一问题在虚拟化场景下更为明显:在host上运行的一个VM,很可能占据比普通应用更大的内存范围(guest OS本身还要引入额外的内存开销),从而使TLB miss率上升的情况进一步恶化。
在强调VM性能的场景下,使用内存大页技术,可以在TLB条目有限的情况下,覆盖更大的内存映射范围,降低TLB miss率,降低VM访存平均延迟,提升VM整体性能。

相同内存页共享

相同内存页共享(KSM: Kernel SamePage Merging)是虚拟化中的一种内存管理技术,是指将一台主机上多个进程的相同内存页精简为一个添加写保护的页面。当多个VM运行相同的操作系统时,就有可能存储完全相同的内存页面。虚拟机管理程序(Hypervisor)会在每个内存页面上分配哈希值,并一位一位的进行比较,一旦不同页面的哈希值相匹配,就说明存在相同的内存页面。如果Hypervisor确认了同一主机上的多个VM有完全相同的内存页面,它会保留其中一份,而其它页面用指针代替,这样就释放了很多内存空间。
NFV场景下KVM虚拟机的性能优化
KSM不能用于内存很大的页面,因为通常情况下,只有小内存页才能完全相同,在使用了大页内存技术时,效果会显著降低。另外,如果一台VM引用的内存页面发生变化,Hypervisor就不得不向内存信息写入一个新页面,同时改变指针信息,这个操作会导致较大的延迟。
在NFV场景中,VM要求使用大页内存,并且对I/O的延迟要求较高,因此,需关闭相同内存页共享功能。

超分配

超分配指的是CPU、内存等资源分配时分配的总数量超出实际的数量,利用的是闲置资源的复用原理来实现的,OpenStack上默认CPU超分比是1:16,内存是1:5。但是当使用的资源超过实际的总量时,势必会导致有些应用得不到及时响应或由于申请不到资源而处于排队等待资源的状态;同时,超分配功能由于增加了资源调度的开销,还有可能降低响应速度。
在部署有对性能敏感的NFV应用的VIM上,需要关闭所有超分配,包括CPU、内存和存储的超分。同时,不允许使用内存气球(virio-balloon)。

vhost网络

virtio 是在半虚拟化管理程序中的一组通用模拟设备的抽象,与纯软件模拟的设备相比,virtio省去了纯模拟模式下的异常捕获环节,Guest OS可以和QEMU的IO模块直接通信,因此拥有更高的IO性能,几乎可以和原生系统差不多。

NFV场景下KVM虚拟机的性能优化

virtio在宿主机中的后端处理程序(back-end)一般是由用户空间的QEMU提供的,然而如果对于网络IO请求的后端处理能够在在内核空间来完成,则效率会更高,会提高网络吞吐量和减少网络延迟。vhost技术对virtio-net进行了优化,在内核中加入了vhost-net.ko模块,它是作为一个内核级别的后端处理程序,将virtio-net的后端处理任务放到内核空间中执行,省去内核空间到用户空间的切换,从而提高效率。

SR-IOV网卡

PCI pass-through让VM能够直接访问物理设备,使得虚拟机的性能几乎达到裸设备的水平。SR-IOV继承自pass-through技术,通过VT-d/IOMMU减少地址转换和地址空间保护的开销,解决了pass-through只能被一台虚拟机访问的问题,一个PCIe设备不仅可以导出多个PCI PF,还可以导出共享该设备上的资源的一组VF。但如果对VM有实时迁移的需求,则不能用SR-IOV。
NFV场景下KVM虚拟机的性能优化
SR-IOV技术将VF直通给VM使用,Hypervisor需要感知链路状态,当SR-IOV网口的链路断开时,其上所有VF的链路状态也会断开,VM内部的相关网卡也会变更为Down状态。Hypervisor可以打开SR-IOV网卡的桥接功能,也即同一个SR-IOV网口上的2个VF交换数据时,直接在网卡内部转发,而无需通过物理交换机。

OVS采用DPDK

DPDK(Data Plane Development Kit)加速的OVS与原始OVS的区别在于,从OVS连接的某个网络端口接收到的报文不需要openvswitch.ko内核态的处理,报文通过DPDK PMD驱动直接到达用户态ovs-vswitchd里。
NFV场景下KVM虚拟机的性能优化
启用DPDK加速的虚拟交换机需支持NUMA感知(IO-NUMA亲和性),也即从各个NUMA节点平均分配CPU核和内存资源供OVS和DPDK进程使用,当为VM启用NUMA亲和性时,由与VM同NUMA node的CPU核和内存处理vNIC的数据转发请求。

多队列vNIC

通过开启vNIC的多队列,并将各个队列通过中断绑定到不同的核上,可以提高网卡收发性能,满足网络高IO的需求。OVS类型的vNIC的队列数量取决于虚拟机vCPU数量,SR-IOV类型的vNIC的队列数量取决于VF。
可以设置每个队列的CPU亲和性,将同一个队列的tx/rx绑定到同一个核上,避免核间数据交互,提高cache命中率。可以关闭irqbalance服务,设置队列的中断亲和(IRQ affinity),将一个队列的中断绑定到一个核上,避免平行收包导致的乱序问题。
在使用virtio类型的vNIC时,Tap设备上的tx队列默认长度是500,可以增加队列长度来降低丢包率,提高性能和可靠性。

小结

上面的性能优化措施主要涉及CPU、内存、网络,由于运营商NFV场景下不允许VM本地启动,必须要使用存储卷,本文没有介绍存储的优化,以后如果有进一步分析再来补充。
其实,如果对上面各项有一定理解后会发现,所有优化都围绕下面几个简单原则:
1.NUMA架构下减少QPI(QuickPath Interconnect)的使用,即减少Node之间的远程访问
2.尽可能使用CPU高速缓存,提高命中率,减少内存地址转换次数
3.减少Linux内核态和用户态的转换,直接pass-through利用下层资源,Host OS和Guest OS可以分别优化

4.降低CPU中断次数,尝试使用轮询算法

NFV场景下KVM虚拟机的性能优化