当前位置: 首页 > news >正文

从100万PPS到10万PPS:一次高性能网关性能雪崩的根因分析与架构重构

一、问题背景

某运营商边缘节点部署了一套用户面网关。

功能非常简单:

N3接口 | | [ Gateway ] | | N6接口

核心流程:

收包 ↓ 会话查找 ↓ 策略匹配 ↓ 转发

实验室压测数据:

指标数值
CPU32 Core
流量64B
PPS100万
时延<100us

看起来非常健康。

然而上线后不到两天,出现严重告警:

CPU达到95% 业务时延超过20ms 丢包率超过15%

更奇怪的是:

流量只有12万PPS

按理说距离实验室极限还有很大空间。

为什么会出现这种情况?


二、第一步定位:CPU到底在干什么

首先查看系统CPU。

top

发现:

user: 85% sys : 12% idle: 3%

说明CPU确实被消耗掉了。

继续:

perf top

热点函数如下:

__netif_receive_skb ip_rcv ip_forward fib_lookup nf_hook_slow

占比超过70%。

这意味着:

CPU大量时间消耗在Linux协议栈

而不是业务逻辑。


三、Linux协议栈为什么慢

很多开发者认为:

转发包 ≈ memcpy

实际上完全不是。

一个数据包从网卡到应用层大致经过:

NIC ↓ DMA ↓ RX Ring ↓ 硬中断 ↓ 软中断 ↓ SKB创建 ↓ 协议栈解析 ↓ 路由查找 ↓ Netfilter ↓ Socket ↓ 用户态

技术插图:

每一步都存在:

Cache Miss 内存访问 上下文切换 锁竞争

尤其SKB。

Linux协议栈中的SKB:

struct sk_buff { ... };

长度超过300字节。

每个包都需要:

申请SKB 初始化SKB 释放SKB

在百万PPS场景下:

每秒百万次内存管理

开销极其巨大。


四、为什么实验室没问题

继续分析流量模型。

实验室:

100万PPS 1000条会话

现网:

12万PPS 200万条会话

这里出现关键差异:

会话规模

五、真正的问题:Cache Miss

会话表结构如下:

struct session { uint64_t seid; uint32_t teid; policy_t *policy; qos_t qos; statistics_t stat; };

总大小约:

256 Bytes

200万条会话:

256 × 2000000 ≈ 512MB

远超CPU Cache。

现代CPU:

L1 Cache 32KB L2 Cache 1MB L3 Cache 30~60MB

而会话表:

512MB

根本放不进去。

结果:

每个包:

Hash ↓ 查表 ↓ 内存访问

几乎都会触发:

LLC Miss

六、如何证明是Cache问题

perf继续分析:

perf stat

结果:

cache-misses cache-references LLC-load-misses

异常高。

进一步:

perf record perf report

热点:

rte_hash_lookup()

占比高达40%。

终于定位:

CPU不是在处理包 而是在等内存

七、NUMA带来的第二次伤害

服务器配置:

2 Socket

NUMA结构:

Socket0 ├ CPU0-15 └ Memory0 Socket1 ├ CPU16-31 └ Memory1

技术插图:

发现:

线程运行在Socket0 会话内存分配在Socket1

于是每次查表:

远程内存访问

延迟增加:

80ns → 150ns+

看似只增加几十纳秒。

但:

100万PPS

累计后就是大量CPU时间浪费。


八、锁竞争开始出现

继续观察:

perf lock report

热点:

pthread_spin_lock

统计模块代码:

session->pkt_cnt++; session->byte_cnt += len;

多个线程共享会话。

因此:

lock ↓ update ↓ unlock

技术插图:

高并发时:

CPU不停争抢Cache Line

形成:

Cache Ping-Pong

九、架构问题浮出水面

原设计:

RX ↓ Worker1 Worker2 Worker3 Worker4 ↓ 共享Session表

问题:

所有线程访问同一份状态

意味着:

锁 Cache同步 NUMA访问

全部出现。


十、高性能网关的正确设计

核心原则:

让数据跟着CPU走 不要让CPU追着数据跑

第一原则:Flow Affinity

同一流量固定进入同一个Worker。

例如:

TEID Hash
worker_id = teid % worker_num;

架构:

Dispatcher | ------------------------- | | | | V V V V W0 W1 W2 W3

同一个TEID永远进入同一个线程。

好处:

无锁

第二原则:状态本地化

不要:

全局Session表

改成:

Worker0 Session Worker1 Session Worker2 Session Worker3 Session

即:

状态归属线程

这样:

无需加锁

第三原则:批处理

不要:

recv(); process(); send();

改成:

rte_eth_rx_burst();

例如:

32 packets

一起处理。

优势:

减少函数调用 提高Cache命中率 提升指令流水线利用率

第四原则:避免共享统计

不要:

global_counter++;

改成:

Per-Core Counter

每核维护:

local_counter

定期汇总。


第五原则:NUMA感知

绑定:

网卡0 ↓ Socket0 ↓ Worker0~15 网卡1 ↓ Socket1 ↓ Worker16~31

原则:

CPU Memory NIC 必须同NUMA

十一、重构后的架构

最终采用:

+------------+ | Dispatcher | +------------+ | --------------------------------- | | | | | V V V V V Worker Worker Worker Worker Worker | | | | | | | | | | Session Session Session Session Session

特点:

Dispatcher

负责:

解析头部 提取TEID Hash分发

不做业务。

Worker

负责:

会话查找 策略执行 转发

Session

归属Worker。

无锁 无共享

十二、最终性能结果

优化前:

指标数值
PPS12万
时延20ms
丢包15%

优化后:

指标数值
PPS180万
时延110us
丢包0

提升:

15倍以上

而业务逻辑几乎没有变化。

变化的只是:

架构 缓存利用 线程模型 内存布局

结语

高性能网关开发中,最大的性能瓶颈往往不是算法复杂度,而是数据访问方式。实际工程里,性能雪崩通常来自三个方面:

  1. Cache Miss导致CPU长期等待内存;
  2. NUMA跨节点访问导致延迟放大;
  3. 共享状态和锁竞争导致多核扩展性失效。

对于5G UPF、CGNAT、DPI、边缘网关等系统,真正有效的设计思路并不是不断优化代码细节,而是在架构层面坚持几个原则:

Flow Affinity State Locality Batch Processing Per-Core Design NUMA Awareness

当数据始终停留在本地CPU缓存中时,系统才能真正发挥现代多核服务器和DPDK框架的性能潜力。这也是高性能网络设备从几十万PPS迈向千万PPS最关键的一步。

http://www.gsyq.cn/news/1466034.html

相关文章:

  • 别再只懂两两导通了!手把手带你搞懂无刷电机三三导通,为啥它不常用?
  • Mythos模型如何重构AI安全与软件漏洞发现范式
  • FPGA上跑通USB转串口的Verilog工程,带全套Quartus编译中间文件
  • LangChain实战入门:从零搭建可运行可修改的AI聊天机器人
  • 2026实测豆包即梦图片水印去除方法!即梦水印能去掉吗合规去除教程
  • 别再死记公式了!用Python+Matplotlib可视化理解吸收率、反射率和透射率
  • 靠谱的运营公司对于企业的发展起着至关重要的作用
  • 数据分析时代终结?不,是决策增强新范式崛起
  • 手机蓝牙发送指令STM32串口接收控制 LED 亮灭
  • 【X5】快速调试验证MIPI摄像头
  • 企业AI编程解决方案:2026最新权威AI编程工具必看开篇
  • Hybrid Search + RRF + Reranker:打造电商 RAG 的精准检索三件套
  • 2026 张家界防水补漏三家品牌横向测评:厨卫屋面地下室修缮哪家靠谱?吉修匠 99.8 分五星稳居榜首 - 吉修匠
  • DenseNet实战:用TensorFlow 2.x在小型数据集上做图像分类,参数少效果也不错
  • 不只是驱动问题:深度解析TI XDS100仿真器EEPROM数据损坏的根源与预防
  • 跳出传统 Agent 桎梏,浅析代码即智能体的底层运行逻辑与落地实践
  • MuleSoft企业级AI编排:让大模型真正融入ERP/CRM核心业务流
  • 2026年高县亲子水上乐园选型指南:龙源溪山泉水乐园深度评测 - 企业名录优选推荐
  • 别再傻傻分不清了!SCI、EI、IEEE到底该投哪个?给研究生和工程师的选刊避坑指南
  • 2026 黄石防水补漏三家品牌横向测评:厨卫屋面地下室修缮哪家靠谱?吉修匠 99.8 分五星稳居榜首 - 吉修匠
  • CMOS图像传感器硬件设计参考图集:含像素结构、读出电路与接口连接详解
  • 宿舍党福音:用40块的斐讯K2+Padavan搞定校园网锐捷6.41认证(静态IP版)
  • C++嵌入式智能车自动驾驶工程包,含双分支开发目录与可编译源码
  • 从‘老师点名’到芯片调度:用生活例子彻底搞懂Round Robin仲裁器的工作原理与设计陷阱
  • PX4飞控调试避坑指南:Offboard模式前必须检查的7个参数(安全第一)
  • 重新定义汽车保养!别只换机油,90%车主忽略的养车真相!
  • 2026年天津滨江道必吃海鲜攻略:本地人私藏的海肠捞饭大王与平价海鲜正餐指南 - 优质企业观察收录
  • SSM架构的Java网上书城实战项目(含前后台+数据库+演示视频)
  • 2026新疆靠谱持证导游TOP8 本地人纯玩高评分推荐 - 盛世西域旅行
  • 2026 三门峡防水补漏三家品牌横向测评:厨卫屋面地下室修缮哪家靠谱?吉修匠 99.8 分五星稳居榜首 - 吉修匠