为什么运营商级 UPF 不会直接把所有 Session 放进 rte_hash?

发布时间:2026/6/3 11:40:50

为什么运营商级 UPF 不会直接把所有 Session 放进 rte_hash? 一、一个看似合理的设计很多开发者刚开始设计 UPF 时都会采用如下思路struct session { uint32_t teid; struct pdr *pdr; struct far *far; struct qer *qer; }; rte_hash_add_key_data( session_table, teid, session);数据包到来后session rte_hash_lookup_data( session_table, teid);然后执行PDR匹配 ↓ FAR处理 ↓ QER处理 ↓ 转发整个逻辑简单清晰。对于10万 Session甚至100万 Session通常都能获得不错的性能。于是很多开发者会产生一个结论Hash查找是O(1) Session问题已经解决但运营商级系统往往在这里踩下第一个大坑。二、问题从100万用户之后开始出现实验室环境中100万 Session往往能够正常运行。然而当规模扩大到500万 1000万 2000万 Session系统开始出现异常PPS下降CPU利用率上升Cache Miss暴涨时延抖动增加很多人第一反应是Hash算法不够快实际上rte_hash 本身通常不是问题。问题在于Hash查找只是开始三、CPU真正关心的不是Hash从算法角度Hash Lookup O(1)非常优秀。但CPU并不理解O(1)CPU只关心数据在哪里例如session hash_lookup(teid);随后pdr session-pdr; far session-far; qer session-qer;这意味着一次Session访问可能触发Hash Bucket访问 ↓ Session访问 ↓ PDR访问 ↓ FAR访问 ↓ QER访问如果这些对象分散在不同内存区域。每一步都可能产生Cache Miss四、从计算瓶颈变成内存瓶颈现代服务器例如Intel Xeon AMD EPYC拥有极强计算能力。CPU执行一条整数指令1~2 Cycle而一次DRAM访问200~400 Cycle也就是说CPU真正浪费时间的地方不是计算。而是等待内存这也是很多UPF系统的核心瓶颈。五、Session越多Cache命中率越低假设1000万 Session每个Session256 Byte总内存约2.5GB而服务器L3 Cache通常30MB~100MB远远无法容纳全部Session。因此绝大多数Session访问都会落到DRAM于是CPU开始频繁等待内存。吞吐量迅速下降。六、运营商系统真正难的是状态管理很多人认为UPF核心是GTP-U实际上GTP-U头部解析只占极少CPU时间。真正复杂的是Session PDR FAR QER URR这些状态对象。对于运营商而言系统真正管理的是用户状态而不是数据包七、为什么共享Session表会越来越慢很多系统采用global_session_table所有Worker共享。看起来节省内存。实际上多个CPU同时访问同一组Hash Bucket会触发Cache Coherency进一步导致MESI同步产生大量额外开销。八、运营商UPF如何解决成熟系统通常采用TEID Hash ↓ Worker0 TEID Hash ↓ Worker1 TEID Hash ↓ Worker2每个Worker维护自己的Session PDR FAR QER这样无锁 无共享 无同步系统扩展能力显著提高。九、为什么状态归属比Hash算法更重要很多工程师会讨论Cuckoo Hash Robin Hood Hash Hopscotch Hash这些算法当然有价值。但对于运营商系统来说决定性能的往往不是Hash如何做而是状态归谁管因为状态归属决定Cache命中率 NUMA访问 同步成本这些因素远比Hash算法本身重要。十、NUMA是第二个隐藏杀手双路服务器通常如下CPU0 ↓ Memory0 CPU1 ↓ Memory1如果CPU0 访问 Memory1则需要经过UPI/QPI延迟明显增加。因此成熟UPF通常要求NIC Queue Worker Session Table Memory Pool全部位于同一NUMA节点。十一、为什么VPP越来越强调对象布局近年来VPP和很多商用UPF都有一个趋势减少指针 增加连续存储例如不要session ↓ pdr ↓ far而是struct session_context { pdr; far; qer; };放在连续内存。这样一次Cache加载即可获得更多信息。大幅降低内存访问次数。十二、真正优秀的数据面系统是什么样的优秀的数据面架构往往具备以下特点Shared-Nothing状态归属明确。NUMA-Aware内存与CPU绑定。Cache-Friendly连续内存布局。Message-Driven控制面通过消息更新状态。Run-To-Completion尽量避免跨核迁移。这些原则远比某个Hash算法重要。十三、从UPF看未来的数据面架构随着5G-A6G边缘计算云核心网的发展。未来系统规模将继续增长。竞争重点正在从谁能跑满100G变成谁能稳定维护 千万Session 亿级Flow而这已经不是简单的转发问题。而是状态系统设计问题十四、总结很多开发者认为TEID ↓ rte_hash ↓ Session就解决了UPF的核心问题。事实上。这只是第一步。当用户规模达到运营商级别时真正的挑战来自Cache命中率NUMA访问状态生命周期多核扩展内存布局此时系统已经不再是一个简单的转发程序而是一套庞大的状态管理系统。对于现代UPF而言Packet决定性能下限 State决定规模上限而理解这一点正是从DPDK开发工程师成长为数据面架构师的重要一步。DPDK专栏https://blog.csdn.net/mrheboyan/category_13164989.html

相关新闻