我在做 DPDK 开发时,判断系统是否健康,通常会先看:

  • PPS
  • CPU
  • 丢包率
  • NIC error
  • descriptor usage

因为默认认为:没有丢包 = 系统没问题。

但我曾经遇到一个非常诡异的问题:

系统:

  • 没有丢包
  • CPU 没打满
  • 网卡正常
  • RX/TX descriptor 正常
  • worker 也没 crash

然而:业务层却明显感觉:“系统越来越卡”。

表现为:

  • RTT 逐渐升高
  • 请求响应越来越慢
  • ping 抖动明显
  • tail latency 爆炸
  • PPS 看起来却依然稳定

最奇怪的是:所有监控:都“正常”。

第一次遇到时,我怀疑过:

  • NUMA
  • false sharing
  • RX descriptor
  • burst 太大
  • CPU 降频

最后才发现:

真正的问题竟然是:queue backlog(队列积压)。

而这个问题,也让我真正理解了:

高性能系统里:“不丢包”不代表“低时延”。

一、问题现场

系统结构:

RX core:收包。

worker core:业务处理。

TX core:发包。

中间通过:DPDK Ring 进行线程通信。

二、系统指标一切正常

监控显示:

CPU

70%

PPS

稳定。

网卡

无 error。

丢包

0

但业务层反馈:

越来越慢

三、真正奇怪的地方

系统不是:“瞬间卡死”。

而是:延迟越来越高。

例如:

初始 RTT

40us

半小时后

200us

高峰期

2ms

但:依然:不丢包。

四、第一反应:是不是 burst 太大

因为:之前遇到过:burst batching delay。

于是:调小:

rte_eth_rx_burst(..., 8)

结果:稍微改善。但问题仍然存在。

五、后来终于发现关键问题

打印:

rte_ring_count()

结果发现:ring 长度:持续增加。

例如:

初始

32

一段时间后

500

高峰期

2000+

这里终于暴露问题。

六、什么是 queue backlog

即:包没有丢。

但:正在队列里排队等待。

七、为什么“不丢包”反而更危险

很多系统:队列很深。

例如:

RX descriptor

software ring

worker queue

TX queue

这些 queue:可以暂时“吞掉”压力。

于是:看起来:系统没丢包。

但实际上:latency 正在疯狂增长。

八、这本质上是“排队论”问题

系统处理速度:略低于:流量进入速度。

例如:

ingress

10.2 Mpps

processing

10.0 Mpps

每秒:

积压:

0.2 M packet

短时间:看不出来。

但时间一长:queue 越来越深。

九、为什么 PPS 看起来仍然正常

因为:系统最终还是:“处理完了”。

所以:吞吐没明显下降。

但:packet 已经在 queue 中等待了很久。

十、这就是 latency creep

即:时延缓慢增长。

它不像:瞬间丢包。

更隐蔽。也更难排查。

十一、为什么 CPU 没打满

因为:瓶颈不一定是:算力。

而可能是:

某个 worker imbalance

某个 flow hotspot

cache miss

memory stall

导致:

pipeline 某一级:

略慢。

十二、进一步理解 pipeline

DPDK 程序本质是:packet pipeline。

结构:

https://images.openai.com/static-rsc-4/yYVxZ4RlXq-0gTzp4AEY-5Of8nUNw_5j2A0bJnNKmwJC9YtJWJf6x8mhBGPkyHyiF5oU0OCLyv07-5EK_zBIXqIvAvdFHvG4ZmJAPz2JIpyGZOW06o3A9WHeM4PZCWMBGxCkXIas2G1xv_FeN4OeACCPGg97pXzgQWLpDZEhQQl7E20YL-suyupI9dFVRoBG?purpose=fullsize

https://images.openai.com/static-rsc-4/whPDnlk9u5-lTpnFzFl0lLBiMfgfQz6x8ikUdtKVcTZBkF6yYBycweGijNe36LsNDHhunIxGwG7prlKySkOT8aML_fMjtZWal3v-dVXsNmTnakCWZkW21NhXer4cgKQNBR9dhg_9KxjryJ3Hjb_JsPxa17PCv9Mq9yVQo3Pp22maKJs0HauOeLwO2PO8iEZc?purpose=fullsize

https://images.openai.com/static-rsc-4/RBuHjNszfrInd3eanCSwA7KVXnxWDPhRMqlk6E91TD-GqnL-EHLxradAp4bz-Whv2ocd3Z-0HvzhKsHV-72VwZKA7uLbd3VEa7mFid-Z5NU3mM4uBigtIDDpOJjYM_pAsWPBMl4IapJUL5F5SWc49lT2TgwgPFvteSvzBt_gWnaknGS3cQkCfzuriUyKgssk?purpose=fullsize

RX -> ring -> worker -> TX

只要任意一级:处理略慢。

queue 就会积压。

十三、为什么 latency 会指数恶化

因为:queue waiting time:不是线性增长。

在高 utilization 下:会急剧放大。

这是经典:queueing theory。

十四、一个非常经典的误区

很多人优化:

只关注:

maximum throughput

但真实系统:更重要的是:sustained throughput。

即:长期稳定处理能力。

十五、真正危险的是“长期略慢”

如果:worker 永远比 ingress 慢:

1%

最终:queue 一定爆炸。

只是:时间问题。

十六、为什么大 queue 有时是坏事

很多人喜欢:

把 ring 调很大

因为:“不容易丢包”。

但实际上:大 queue:

可能只是:把丢包变成高延迟。

十七、为什么 tail latency 会爆炸

因为:后进入 queue 的 packet:必须等待:前面所有 packet。

于是:

average latency

可能正常。

P99/P999

会非常难看。

十八、真正修复思路

后来做了几个关键优化。

1. 增加 backpressure

当 queue 超过 watermark:主动限流。

2. ring 设置合理大小

避免无限积压。

3. hotspot flow 分流

避免单 worker 被打爆。

4. worker pipeline 优化

减少单包处理波动。

十九、另一个关键优化:及时丢包

后来甚至主动:

early drop

即:queue 过深时:提前丢弃。

二十、为什么“主动丢包”反而更好

因为:真实业务:通常:更怕高时延。

而不是:少量丢包。

尤其:

实时语音

游戏

金融

高 latency:

比 packet loss 更致命。

二十一、优化后结果

优化前:

指标 数值
PPS 稳定
Avg RTT 60us
P999 8ms

优化后:

指标 数值
PPS 略降
Avg RTT 45us
P999 120us

业务体验:大幅提升。

二十二、为什么很多 benchmark 没意义

很多 benchmark:

只看:

是否丢包

或者:

最大 PPS

但真实系统:真正关键的是:

queue depth

latency stability

tail latency

sustained load

二十三、进一步理解 DPDK 哲学

DPDK 真正复杂的部分:从来不是:API。

而是:pipeline behavior。

因为:高 PPS 系统:本质就是:

queue

scheduling

buffering

backpressure

之间的平衡。

二十四、工程经验总结

做高性能网络开发:

一定要监控:

ring depth

queue latency

burst accumulation

worker imbalance

P99/P999 latency

不要只看:

drop=0

二十五、这次排查真正学到什么

以前我以为:“没有丢包”:就代表系统健康。

后来才意识到:真正危险的是:queue silently growing。

因为:系统可能正在:慢慢进入:高延迟状态。而你却完全看不出来。

二十六、总结

为什么 DPDK 程序没有丢包,但业务却越来越“卡”?

很多时候不是:

  • CPU 不够
  • NUMA 问题
  • NIC 问题

而是:queue backlog。

通过这次问题,我们真正理解了:

核心概念

  • queue backlog
  • pipeline latency
  • backpressure
  • tail latency
  • queueing theory
  • sustained throughput

这也是高性能网络开发真正进入“系统稳定性优化”的开始:

系统最危险的时候,可能并不是:开始丢包。

而是:还没丢包。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐