一、问题背景裸机性能很好上云后直接腰斩年前我们做一个基于 DPDK 的 5G UPF 数据面。最开始系统跑在裸机双路 Xeon 25G Intel NIC DPDK PMD压测结果64B 小包 20Mpps系统表现非常稳定。于是项目开始进入 NFV 化部署OpenStackKVMSR-IOVNUMAKubernetes架构变成NIC PF ↓ SR-IOV VF ↓ KVM Guest ↓ DPDK UPF结果系统性能直接暴跌。二、最开始我们以为是“虚拟化损耗”最初大家觉得虚拟化本来就有损耗但问题是损耗远远超出预期。裸机20Mpps虚拟机只有 7~8Mpps更严重的是latency 抖动queue 不均衡CPU 飙升PPS 波动而 DPDK 程序几乎没变于是真正的问题开始了。三、DPDK 在虚拟化环境中瓶颈已经变了很多人理解 DPDK绕过 Linux 网络栈这没错。但裸机 DPDK 的核心优化对象是内核协议栈而虚拟化环境中真正的问题变成了硬件拓扑包括PCIeIOMMUNUMAVF 中断DMA 路径Hypervisor 调度也就是说DPDK 在虚拟化环境中已经不仅仅是网络问题而是系统架构问题四、第一个坑SR-IOV 并不等于“裸机性能”很多人以为SR-IOV 直通其实并不准确。SR-IOV本质是VFVirtual Function也就是说网卡会把硬件资源切片给多个虚拟机。问题在于VF并不是完整 PF。很多资源会缩水。例如Queue 数量RSS 能力Flow DirectorDescriptor 深度Buffer 能力于是大量系统在 VF 环境天然 PPS 更低五、第二个坑IOMMU 才是真正的隐藏杀手后来我们发现系统开启intel_iommuon后。PPS 明显下降。为什么因为DPDK DMA本质是NIC DMA 到 HugePage而 IOMMU会对 DMA进行地址转换这意味着NIC 每次 DMA 都需要IOTLB 查询如果 miss就会page walk高 PPS 下。这个开销非常恐怖。六、为什么小包场景下降最明显因为小包意味着PPS 极高例如64B 小包 ≈ 数千万 DMA于是IOTLB miss会被无限放大。后来我们改成1GB HugePage后。性能明显改善。因为IOTLB 压力下降七、第三个坑vNUMA 配错后性能直接雪崩后来我们又发现虚拟机配置8 vCPU但实际上跨 NUMA例如VF 在 NUMA0VM vCPU 在 NUMA1HugePage 在 NUMA1于是DMA必须跨 Socket导致latency 增加memory bandwidth 下降LLC miss 飙升最终PPS 崩掉。八、为什么很多 OpenStack 环境 DPDK 性能特别差因为OpenStack 默认并不关心数据面 locality例如Nova 调度可能随机分配 vCPUHugePage可能不在同一 NUMAVF也可能不在同一 PCIe Root Complex于是DPDK 系统虽然能跑。但实际上已经完全违背 locality九、第四个坑CPU Pinning 不只是“绑核”很多人喜欢taskset但真正高性能 DPDK。CPU Pinning远比想象复杂。因为还涉及Hyper-Threadingsibling coreLLC sharingscheduler domain例如两个 PMD Thread如果跑在同一个物理核 SMT会共享L1L2execution unit导致pipeline contention最终PPS 下降。十、VirtIO 为什么性能总是不稳定很多人在 K8S 中使用VirtIO vhost-user但VirtIO 本质仍然依赖共享内存 kick notification因此仍然存在VM Exitkick interruptdescriptor synccache bouncing尤其小包场景性能非常难稳定。十一、为什么 vHost-user 比 VirtIO 更快因为vHost-user把 datapath尽量用户态化减少VM ExitQEMU 参与kernel virtqueue因此cache locality 更好。但本质问题仍然存在共享 ring十二、真正的大坑Queue 不均衡后来我们发现某些 VF Queue负载极高而某些 queue几乎空闲。原因SR-IOV 下RSS 能力被削弱尤其某些 NICVF只支持有限 hash key导致流量倾斜。最终某个 core直接跑满。十三、为什么 DPDK 虚拟化系统更容易出现 Tail Latency因为虚拟化环境会引入VM schedulingvCPU steal timeshared LLCnoisy neighborNUMA remote access于是即使平均 PPS 很高。但P99 latency会极差。这也是很多 NFV 系统实验室很好线上不稳定的原因。十四、真正高性能 NFV 系统怎么设计后来我们彻底重构部署架构。核心原则1. VF、vCPU、HugePage NUMA 对齐必须严格同 NUMA2. One Queue One Core避免共享 queue3. 尽量减少虚拟交换层例如避免OVS Kernel Path优先OVS-DPDK4. 尽量减少 VM Exit避免interrupt-heavyVirtIO kick高频 syscall5. 优先 SR-IOV 直通因为共享 datapath永远比独占 datapath更容易抖动。十五、DPDK 在虚拟化环境中本质已经不是“网络编程”很多人觉得DPDK只是收发包框架但在 NFV 场景。真正优化的已经变成PCIe topologyNUMA localityHypervisor schedulingDMA pathIOTLBcache sharing本质已经进入系统架构工程十六、真正的高性能 NFV比拼的是“硬件理解”很多团队DPDK 代码已经优化得很好。但性能依然差。原因问题根本不在代码。而在硬件拓扑包括哪个 NUMA哪个 PCIe Slot哪个 Root Complex哪个 LLC Domain这些往往比代码优化影响更大。十七、总结很多 DPDK 系统裸机性能极强但一进入OpenStackKVMKubernetesSR-IOV环境系统就开始PPS 暴跌latency 抖动queue 不均衡CPU 飙升根本原因通常不是DPDK 不够快而是虚拟化破坏了硬件 locality真正的大规模 NFV 数据面。最终优化的已经不是网络协议而是整个硬件拓扑与 DMA 路径而这才是现代 DPDK 虚拟化系统最核心的本质。