7.4. 手动计算 OVS-DPDK 参数

本节介绍 OVS-DPDK 如何使用 director network_environment.yaml heat 模板中的参数来配置 CPU 和内存以实现最优性能。使用这些信息评估 Compute 节点上的硬件支持,以及如何对硬件进行分区以优化 OVS-DPDK 部署。

注意

如需有关如何使用 derived_parameters.yaml 工作流生成这些值的更多信息,请参阅 工作流和派生参数概述

注意

在分配 CPU 内核时,始终对 CPU 同级线程或逻辑 CPU 分组到物理内核中。

有关如何决定 Compute 节点上的 CPU 和 NUMA 节点的详情,请参考 发现您的 NUMA 节点拓扑。使用此信息映射 CPU 和其他参数,以支持主机、客户机实例和 OVS-DPDK 进程的需求。

7.4.1. CPU 参数

OVS-DPDK 为 CPU 分区使用以下参数:

OvsPmdCoreList

提供用于 DPDK 轮询模式驱动程序(PMD)的 CPU 内核。选择与 DPDK 接口本地 NUMA 节点关联的 CPU 内核。使用 OvsPmdCoreList 作为 OVS 中的 pmd-cpu-mask 值。对 OvsPmdCoreList 使用以下建议:

  • 对同级的线程连接在一起。
  • 性能取决于为此 PMD 核心列表分配的物理内核数。在与 DPDK NIC 关联的 NUMA 节点上,分配所需的内核。
  • 对于具有 DPDK NIC 的 NUMA 节点,根据性能要求确定物理内核数量,并包含每个物理内核的所有同级线程或逻辑 CPU。
  • 对于没有 DPDK NIC 的 NUMA 节点,请为任何物理内核分配同级线程或逻辑 CPU,除了 NUMA 节点的第一个物理核心除外。
注意

您必须在两个 NUMA 节点上保留 DPDK PMD 线程,即使 NUMA 节点没有关联的 DPDK NIC。

NovaComputeCpuDedicatedSet

可以调度用于固定实例 CPU 的进程的逗号分隔列表或物理主机 CPU 范围。例如,NovaComputeCpuDedicatedSet: [4-12,^8,15] 保留来自 4-12 和 15 的核心,不包括 8。

  • OvsPmdCoreList 中排除所有内核。
  • 包括所有剩余内核。
  • 对同级的线程连接在一起。
NovaComputeCpuSharedSet
用于决定实例仿真程序线程的主机 CPU 编号的逗号分隔列表或范围。
IsolCpusList

与主机进程隔离的一组 CPU 核心。IsolCpusListtuned-profiles-cpu-partitioning 组件的 cpu-partitioning-variable.conf 文件中的 isolated_cores 值。对 IsolCpusList 使用以下建议:

  • 匹配 OvsPmdCoreListNovaComputeCpuDedicatedSet 中的内核数。
  • 对同级的线程连接在一起。
DerivePciWhitelistEnabled

要为虚拟机保留虚拟功能(VF),请使用 NovaPCIPassthrough 参数创建通过 Nova 传递给 Nova 的 VF 列表。列表中排除的 VF 会为主机保留可用。

对于列表中的每个 VF,使用解析到地址值的正则表达式填充 address 参数。

以下是手动列表创建过程的示例。如果在名为 eno2 的设备中启用 NIC 分区,使用以下命令列出 VF 的 PCI 地址:

[heat-admin@compute-0 ~]$ ls -lh /sys/class/net/eno2/device/ | grep virtfn
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn0 -> ../0000:18:06.0
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn1 -> ../0000:18:06.1
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn2 -> ../0000:18:06.2
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn3 -> ../0000:18:06.3
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn4 -> ../0000:18:06.4
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn5 -> ../0000:18:06.5
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn6 -> ../0000:18:06.6
lrwxrwxrwx. 1 root root    0 Apr 16 09:58 virtfn7 -> ../0000:18:06.7

在本例中,VF 0、4 和 6 供 eno2 用于 NIC 分区。手动配置 NovaPCIPassthrough 以包括 VF 1-3、5 和 7,因此排除 VFs 0、4 和 6,如下例所示:

NovaPCIPassthrough:
  - physical_network: "sriovnet2"
  address: {"domain": ".*", "bus": "18", "slot": "06", "function": "[1-3]"}
  - physical_network: "sriovnet2"
  address: {"domain": ".*", "bus": "18", "slot": "06", "function": "[5]"}
  - physical_network: "sriovnet2"
  address: {"domain": ".*", "bus": "18", "slot": "06", "function": "[7]"}

7.4.2. 内存参数

OVS-DPDK 使用下列内存参数:

OvsDpdkMemoryChannels

映射每个 NUMA 节点的 CPU 中的内存频道。OvsDpdkMemoryChannels 是 OVS 中的 other_config:dpdk-extra="-n <value>" 值。观察 OvsDpdkMemoryChannels 的以下建议:

  • 使用 dmidecode -t memory 或您的硬件手册来确定可用的内存通道数。
  • 使用 ls /sys/devices/system/node/node* -d 确定 NUMA 节点的数量。
  • 将可用内存通道数除以 NUMA 节点数。
NovaReservedHostMemory

以 MB 为单位保留主机上任务的内存。NovaReservedHostMemorynova.conf 中 Compute 节点的 reserved_host_memory_mb 值。观察 NovaReservedHostMemory 的以下建议:

  • 使用静态推荐值 4096 MB。
OvsDpdkSocketMemory

指定从每个 NUMA 节点预先分配巨页池的内存量(以 MB 为单位)。OvsDpdkSocketMemory 是 OVS 中的 other_config:dpdk-socket-mem 值。观察 OvsDpdkSocketMemory 的以下建议:

  • 提供 作为用逗号分开的列表。
  • 对于没有 DPDK NIC 的 NUMA 节点,请使用 1024 MB (1GB)的静态建议。
  • 从 NUMA 节点上的每个 NIC 的 MTU 值计算 OvsDpdkSocketMemory 值。
  • 以下驱除 OvsDpdkSocketMemory 的值如下:

    • MEMORY_REQD_PER_MTU = (ROUNDUP_PER_MTU + 800) * (4096 * 64) Bytes

      • 800 是开销值。
      • 4096 * 64 是 mempool 中的数据包数量。
  • 为 NUMA 节点上设置的每个 MTU 值添加 MEMORY_REQD_PER_MTU,再添加另一个 512 MB 作为缓冲区。将值设为 1024 的倍数。

Calculation 示例 - MTU 2000 和 MTU 9000

DPDK NIC dpdk0 和 dpdk1 在同一 NUMA 节点 0 上,分别使用 MTU 9000 和 2000 进行配置。生成内存所需的计算示例如下:

  1. 将 MTU 值向下舍入到最接近 1024 字节。

    The MTU value of 9000 becomes 9216 bytes.
    The MTU value of 2000 becomes 2048 bytes.
  2. 根据这些循环的字节值计算每个 MTU 值所需的内存。

    Memory required for 9000 MTU = (9216 + 800) * (4096*64) = 2625634304
    Memory required for 2000 MTU = (2048 + 800) * (4096*64) = 746586112
  3. 计算所需的总内存总量(以字节为单位)。

    2625634304 + 746586112 + 536870912 = 3909091328 bytes.

    此计算代表( MTU 为 9000 所需要的内存)+(MTU 为 2000)+(512 MB 缓冲所需的内存)。

  4. 将所需的总内存转换为 MB。

    3909091328 / (1024*1024) = 3728 MB.
  5. 将该值向上舍入到最接近的 1024。

    3724 MB rounds up to 4096 MB.
  6. 使用这个值设置 OvsDpdkSocketMemory

        OvsDpdkSocketMemory: "4096,1024"

Calculation 示例 - MTU 2000

DPDK NIC dpdk0 和 dpdk1 在同一 NUMA 节点 0 上,每个节点都配置了 2000 的 MTU。生成内存所需的计算示例如下:

  1. 将 MTU 值向下舍入到最接近 1024 字节。

    The MTU value of 2000 becomes 2048 bytes.
  2. 根据这些循环的字节值计算每个 MTU 值所需的内存。

    Memory required for 2000 MTU = (2048 + 800) * (4096*64) = 746586112
  3. 计算所需的总内存总量(以字节为单位)。

    746586112 + 536870912 = 1283457024 bytes.

    此计算代表(MTU 为 2000)+(512 MB 缓冲)所需的内存。

  4. 将所需的总内存转换为 MB。

    1283457024 / (1024*1024) = 1224 MB.
  5. 将该值向上舍入到最接近 1024 的倍数。

    1224 MB rounds up to 2048 MB.
  6. 使用这个值设置 OvsDpdkSocketMemory

        OvsDpdkSocketMemory: "2048,1024"

7.4.3. 网络参数

OvsDpdkDriverType
设置 DPDK 使用的驱动程序类型。使用 vfio-pci 的默认值。
NeutronDatapathType
OVS 网桥的数据路径类型。DPDK 使用 netdev 的默认值。
NeutronVhostuserSocketDir
为 OVS 设置 vhost-user 套接字目录。将 /var/lib/vhost_sockets 用于 vhost 客户端模式。

7.4.4. 其他参数

NovaSchedulerDefaultFilters
提供有序的过滤器列表,计算节点用于为请求的客户机实例查找匹配的 Compute 节点。
VhostuserSocketGroup
设置 vhost-user 套接字目录组。默认值为 qemu。将 VhostuserSocketGroup 设置为 hugetlbfs,以便 ovs-vswitchdqemu 进程可以访问配置 virtio-net 设备的共享巨页和 unix 套接字。此值特定于角色,应当应用到利用 OVS-DPDK 的任何角色。
KernelArgs

在引导时为 Compute 节点提供多个内核参数 /etc/default/grub。根据您的配置添加以下值:

  • hugepagesz :设置 CPU 中巨页的大小。这个值可能因 CPU 硬件而异。为 OVS-DPDK 部署(默认_hugepagesz=1GB hugepagesz=1G )设置为 1G。使用此命令检查 pdpe1gb CPU 标记,该标记确认您的 CPU 支持 1G。

    lshw -class processor | grep pdpe1gb
  • hugepages count :根据可用的主机内存设置巨页数量。使用大多数可用内存,NovaReservedHostMemory 除外。您还必须在 Compute 节点的类型中配置巨页数值。
  • IOMMU: 对于 Intel CPU,添加 "intel_iommu=on iommu=pt"
  • isolcpus :设置用于调优的 CPU 内核。这个值与 IsolCpusList 匹配。

有关 CPU 隔离的更多信息,请参阅 RHEL 8 和 RHEL 9 的红帽知识库解决方案 OpenStack CPU 隔离指导

7.4.5. 实例额外规格

在 NFV 环境中部署实例之前,先创建一个利用 CPU 固定、巨页和仿真程序线程固定的类别。

hw:cpu_policy
当此参数设为 dedicated 时,客户机使用固定 CPU。从带有此参数集的类别创建的实例具有有效的过量使用比 1:1。默认值为 共享
hw:mem_page_size

将此参数设置为带有标准后缀(例如 4KB8MB1GB)的特定值的有效字符串。使用 1GB 匹配 hugepagesz 引导参数。从 boot 参数中减去 OvsDpdkSocketMemory,计算虚拟机的巨页数量。以下值也有效:

  • small (默认)- 使用最小页面大小
  • large - 只使用大页大小。(x86 架构上的 2MB 或 1GB)
  • any - 计算驱动程序都可尝试使用大页,但如果不可用,则默认为 small。
hw:emulator_threads_policy
将此参数的值设为 share,以便仿真程序线程锁定在 heat 参数( NovaComputeCpuSharedSet 中已标识)的 CPU。如果仿真程序线程在带有轮询模式驱动程序(PMD)或实时处理的 vCPU 上运行,您可以遇到负面影响,如数据包丢失。