OpenStack Nova 高性能虚拟机之 NUMA 架构亲和
发布网友
发布时间:2024-10-08 19:28
我来回答
共1个回答
热心网友
时间:2024-11-06 00:42
在 Icehouse 版本之前,Nova 实现的 NUMA 亲和机制并未考虑 Host NUMA 的情况,这导致 Libvirt 在默认情况下可能会发生跨 NUMA node 获取 CPU/Memory 资源的情况,进而影响 Guest 的性能。然而,从 Juno 版本开始,Openstack 新增了 NUMA 特性,用户可以通过将 Guest 的 vCPU/Memory 绑定到 Host NUMA Node 上,从而提升 Guest 的性能。
除了 NUMA 基本概念之外,Nova 还自定义了一些对象概念。首先,vCPU 和 pCPU 的定义具有一定的迷惑性,简单来说,虚拟机实际上是宿主机的一个进程,而虚拟机 CPU 则是宿主机进程中的一个特殊线程。引入 pCPU 和 vCPU 的概念是为了让上层逻辑能够屏蔽机器 NUMA 拓扑的复杂性。其次,Thread siblings 对象的引入是为了无论服务器是否开启了超线程,Nova 都能支持物理 CPU 绑定的功能。
操作系统发行版许可证(Licensing)可能会严格约束操作系统能够支持的最大 sockets 数量,进而影响服务器上可运行虚拟机的数量。因此,在这种情况下,应该更加偏向于使用 core 来作为 vCPU,而不是 socket。由于许可证的影响,建议用户在上传镜像到 Glance 时,指明一个运行镜像最佳的 CPU 拓扑。云平台管理员也可以通过修改 CPU 拓扑的默认值来避免用户超出许可*。
宿主机 CPU 拓扑的方式对其自身性能具有很大影响。例如,多 Socket 单 Core 拓扑在 Socket 间协作要通过外部总线通信,导致通信开销大、线程切换开销大、Cache 数据一致性难维持等问题。相比之下,单 Socket 多 Core 拓扑在多 Core 之间通信开销小、Socket 占位面积小等优势明显。但需要注意的是,当需要运行多个“大程序”时,单 Socket 多 Core 拓扑在多任务、高并发、高消耗内存的程序运行环境中效率会变得非常低下。
CPU 架构对于并发程序设计而言,主要需要考虑两个问题,一个是内存可见性问题,一个是 Cache 一致性问题。超线程技术并非万能药,开启超线程后,Core 的总计算能力是否提升以及提升的幅度和业务模型相关,平均提升在 20%-30% 左右。但超线程对 Core 的执行资源的争抢,业务的执行时延也会相应增加。当超线程相互竞争时,超线程的计算能力相比不开超线程时的物理核甚至会下降 30% 左右。
在 NUMA 拓扑方面,现在的服务器基本都支持 NUMA 拓扑。NUMA 具有高存储访问带宽、有效的 Cache 效率以及灵活 PCIe I/O 设备的布局设计等优势。但由于 NUMA 跨节点远程内存访问不仅延时高、带宽低、消耗大,还可能需要处理数据一致性的问题,因此,虚拟机的 vCPU 和内存在 NUMA 节点上的错误布局,将会导致宿主机资源的严重浪费。因此,标准的策略是尽量将一个虚拟机完全局限在单个 NUMA 节点内。
在 Nova 上应用 NUMA 亲和来创建高性能虚拟机时,首先需要判断该物理服务器是否支持 NUMA 功能,然后查看物理服务器的 NUMA 拓扑,接着查看物理服务器是否开启了超线程。Nova 的 NUMA 亲和原则是:将 Guest vCPU/Mem 都分配在同一个 NUMA Node 上,充分使用 NUMA node local memory,避免跨 Node 访问 remote memory。
在 Nova 中,可以通过 Flavor extra-specs 或 Image Metadata 来设定 Guest NUMA topology。Nova Scheler 会根据参数 hw:numa_nodes 来决定如何映射 Guest NUMA node。如果设定了 hw:numa_cpus.N 和 hw:numa_mem.N,那么 Nova 将会根据这些参数进行 vCPU 和 pCPU 的绑定。需要注意的是,如果 hw:numa_cpus.N 和 hw:numa_mem.N 的设定值大于虚拟机本身可用的 CPUs/Mem,则触发异常。