一、故障背景
某运营商数据中心部署了一套基于DPDK开发的100G高性能交换机。
系统承担:
- 二层交换
- IPv4/IPv6三层转发
- VXLAN Gateway
- ACL过滤
服务器配置如下:
| 配置项 | 参数 |
|---|---|
| CPU | Intel Xeon Gold 双路 |
| 网卡 | Intel 100GbE |
| DPDK | 24.11 LTS |
| HugePage | 1GB HugePage |
| PMD Worker | 16个 |
系统上线半年,一直稳定运行。
某次版本升级以后,压力测试发现一个奇怪现象。
开始10分钟:系统性能正常。
持续运行约30分钟以后:PPS开始出现周期性下降。
每隔几十秒:都会出现一次明显下降。持续时间约几十毫秒。随后恢复正常。
整个过程不断重复。
二、第一轮排查
首先怀疑:
是不是网卡出现异常?
查看DPDK统计:
struct rte_eth_stats stats;
rte_eth_stats_get(port, &stats);
结果:
imissed = 0
ierrors = 0
rx_nombuf = 0
继续查看:
ethtool -S eth0
重点统计:
- CRC Error
- RX Miss
- DMA Error
- Buffer Error
全部为0。
说明:
网卡完全正常。
核心知识点一
DPDK统计的是软件能够观察到的状态。
如果性能下降发生在:
- Cache竞争
- 内存分配
- CPU同步
这些问题通常不会反映到网卡统计信息中。
因此:
没有Error,
并不意味着没有性能问题。
三、第二轮排查
继续观察:
每个PMD Worker。
结果如下:
| Worker | CPU |
|---|---|
| Worker0 | 100% |
| Worker1 | 100% |
| Worker2 | 100% |
| …… | 100% |
CPU全部100%。
这完全符合DPDK Poll Mode Driver的工作方式。
继续统计:RSS分布。
发现:16个Worker流量几乎一致。
RX Queue:没有积压。
TX Queue:没有阻塞。
说明:
既不是RSS失衡。
也不是Queue瓶颈。
核心知识点二
DPDK系统中:
CPU利用率并不是判断性能瓶颈的重要指标。
真正需要关注的是:
- 每Packet Cycle
- IPC
- Cache命中率
- 内存访问模式
四、Perf开始暴露异常
既然:
软件逻辑没有问题。
开始使用:
perf stat \
-e cycles,instructions,cache-misses \
-p <PMD_PID>
得到如下结果:
| 指标 | 正常阶段 | 抖动阶段 |
|---|---|---|
| Instructions | 基本一致 | 基本一致 |
| Cycles | 略增加 | ↑↑ |
| IPC | 1.92 | 1.61 |
| Cache Miss | 小幅增加 | 小幅增加 |
Cache Miss:并没有明显变化。
但是:
CPU执行效率明显下降。
说明:
CPU不是在计算,而是在等待。
等待什么?
继续分析。
五、真正的异常开始出现
为了进一步定位。
我们开启DPDK Telemetry,并增加了Mempool统计:
rte_mempool_avail_count(mp);
rte_mempool_in_use_count(mp);
压测过程中发现:
每当系统吞吐下降时:Global Pool对象数量开始剧烈波动。
而Per-lcore Cache几乎全部被耗尽。
几十毫秒后Cache重新填满,性能恢复。
又过一段时间。
再次重复。
这说明:
问题并不是:mbuf数量不足。
而是:mbuf流转路径出现了异常。

核心知识点三
DPDK申请mbuf:
并不是:
每次都访问Global Pool。
真正的数据路径:
首先经过:Per-lcore Cache。
只有Cache不足。
才会访问:Global Pool。
因此:
Per-lcore Cache:才是真正决定高速收发性能的关键。
六、Mempool到底是如何工作的?
很多开发者认为:
Mempool就是一个对象池。
实际上:
DPDK为了减少多核竞争,在Global Pool之外,又增加了一层:Per-lcore Cache。
真正结构如下:
Global Pool
│
┌──────────────┼──────────────┐
│ │ │
Worker0 Cache Worker1 Cache Worker2 Cache
│ │ │
mbuf mbuf mbuf
正常情况下:
Worker收包。释放mbuf。再次申请mbuf。几乎全部发生在:自己的Cache里面。
整个过程不会访问Global Pool。
也不会产生跨核竞争。
这也是DPDK能够支撑数亿PPS的重要原因之一。
但是。
如果:Per-lcore Cache配置不合理。
整个机制反而会成为性能瓶颈。
七、问题逐渐浮出水面
继续阅读DPDK源码。
定位到:lib/mempool/rte_mempool.c
其中:rte_mempool_get_bulk()
首先尝试:从Per-lcore Cache获取对象。
只有:Cache不足。
才会访问:Global Ring。
而Global Ring正是:所有Worker共享的资源。
问题:
似乎开始指向这里……
739

被折叠的 条评论
为什么被折叠?



