TIPS之 Nova高性能虚拟机CPU绑定

Nova高性能虚拟机之CPU绑定

Posted by 董江 on Wednesday, July 10, 2024

1. 背景

Nova Scheduler调度:

  • 由于ECS是vCPU超卖的,因此如果调度在同一 的pCPU上,会引起调度异常导致创建资源异常;
  • ECS在使用过程中,真实的ECS大量线程请求到比较集中的pCPU上,也容易引发异常;

2. 介绍

vCPU 调度示意图:

HostOS 将 vCPU 当普通线程来进行调度,那么 vCPU 的调度与性能问题实际上就是 Linux 线程在多处理器计算平台中的调度与性能问题。提高虚拟机 vCPU 的性能,需要贯彻三点原则:

  • 减少多线程上下文切换的性能损耗
  • 减少用户线程模式切换的性能损耗
  • 提高高速缓存的命中率

实现这些原则的手段大致上有两种:

  • 规划出给 Guest 专用的 pCPU s,并且 vCPUs 和 pCPUs 所拥有的 Cores 数量相近
  • 将 vCPU 绑定到指定的 pCPU 上运行

3. 解决方案

3.1 CPU 绑定策略

CPU 绑定策略机制经常会结合 NUMA topology 一起使用, 实现vCPU与pCPU亲和性;

openstack flavor set FLAVOR-NAME \
    --property hw:cpu_policy=dedicated \
    --property hw:cpu_thread_policy=isolate
  • CPU-POLICY:
    • shared (default):不独占 pCPU 策略,允许 vCPUs 在不同的 pCPUs 间浮动,尽管 vCPUs 受到 NUMA node 的限制也是如此
    • dedicated:独占 pCPU 策略,Guest 的 vCPUs 将会严格的 pinned 到 pCPUs 的集合中。在没有明确配置 Guest NUMA Topology 的情况下,Nova 会将每个 vCPU 都作为一个 Socket 中的一个 Core;如果已经明确的配置了 Guest NUMA Topology 的话,那么虚拟机就会严格按照 Guest NUMA Topology 和 Host NUMA Topology 的映射关系将 vCPUs pinned to pCPUs,pCPUs 可能是一个 Core 或是一个 Thread,根据 Host 实际的处理器体系结构以及 CPU-THREAD-POLICY 来共同决定。此时的 CPU overcommit ratio 为 1.0(不支持 CPU 超配),避免 vCPU 的数量大于 Core 的数量导致的线程上下文切换损耗。
  • CPU-THREAD-POLICY:
    • prefer (default):如果 Host 开启了超线程,则 vCPU 优先选择在 Siblings Thread 中运行,即所有的 vCPU 都只会考虑 siblings。例如:4 个逻辑核属于同一 NUMA,其中 CPU1 和 CPU2 属于相同物理核,CPU3 和 CPU4 属于不同的物理核,若此时创建一个 Flavor vCPU 为 4 的云主机会创建失败,因为 siblings 只有 [set([1, 2])];否则,vCPU 优先选择在 Core 上运行。
    • isolate(vCPU 性能最好):vCPU 必须绑定到 Core 上。如果 Host 没有开启超线程,则理所当然会将 vCPU 绑定到 Core 上;相反,如果 Host 开启了超线程,则 vCPU 会被绑定到 Siblings Thread 的一个 Thread 中,并且其他的 vCPU 不会再被分配到该 Core 上,相当于 vCPU 独占一个 Core,避免 Siblings Thread 竞争。
    • require(vCPU 数量最多):vCPU 必须绑定到 Thread 上。Host 必须开启超线程,每个 vCPU 都会被绑定到 Thread 上,直到 Thread 用完为止。如果没有开启的话,那么该 Host 不会出现在 Nova Scheduler 的调度名单中。

3.2 vcpu_pin_set 配置项

vcpu_pin_set 是 compute node 上的 nova.conf 配置项,是 OpenStack 最早设计用于限定 Guest 可以使用 compute node 上的 pCPUs 的范围,解决了下述问题:

currently the instances can use all of the pcpu of compute node, the host may become slowly when vcpus of instances are busy, so we need to pin vcpus to the specific pcpus of host instead of all pcpus. the vcpu xml conf of libvirt will change to like this: 
<vcpu cpuset="4-12,^8,15">1</vcpu>

简单来说,就是为了让用户一方面可以划分出 Guest 专用的 pCPUs 以保证性能,另一方面也是为了防止 Guest 过分争抢 Host 进程的 CPU 资源,为 Host 适当的留下一些 CPU 以保证正常运作。

3.3 host nava进程绑定预留核上

Guest 专用执行,并确保nava相关进程跑在预留的pCPU上;

$ ps aux | grep "nava" | awk -F" " '{print $2}'
23772
208
...
4562

$ taskset -cp 0,1 23772
$ taskset -cp 0,1 4562

「如果这篇文章对你有用,请随意打赏」

Kubeservice博客

如果这篇文章对你有用,请随意打赏

使用微信扫描二维码完成支付