
一、一个典型的现象很多开发者第一次接触 DPDK 时都会产生一种错觉。他们往往拥有丰富的 Linux 网络开发经验Socket 编程epollTCP ServerHTTP ServerNginx 模块开发Redis 网络框架甚至能够设计支撑十万级并发连接的系统。于是他们认为DPDK 只是把 Socket 换成了用户态收发包然而现实往往并非如此。很多项目中都会出现类似情况第一版 DPDK 程序很快完成功能也正常。但是随着业务复杂度增加CPU 利用率越来越高多核扩展能力越来越差Session 管理越来越混乱系统架构越来越复杂最终开发团队发现问题并不是 DPDK 不够快而是过去积累的很多设计经验开始失效。二、Linux 网络编程解决的是什么问题先看传统 Linux 网络模型。以一个 Web Server 为例Client ↓ Socket ↓ TCP ↓ Application应用程序面对的是连接开发者思考的问题是一个连接对应一个用户一个连接对应一个会话一个连接对应一个状态因此形成了典型的设计模式struct connection { int fd; ... };整个系统围绕连接组织。连接是核心抽象。三、DPDK 面对的根本不是连接DPDK 世界完全不同。例如一个 UPFN3 ↓ GTP-U ↓ Session Lookup ↓ PDR/FAR ↓ N6对于数据面来说。根本不存在连接它面对的是流量或者更准确地说Packet Stream每秒可能有数百万甚至数千万 Packet持续流动。这里的核心对象已经不是连接。而是Flow四、连接思维与流量思维的区别Linux 网络编程中开发者习惯这样思考用户来了 建立连接 处理请求 关闭连接而 DPDK 世界中开发者必须思考报文来了 属于哪个流 应该走什么策略 如何最快转发两者最大的区别在于Linux 关注连接生命周期DPDK 关注流量生命周期这是两个完全不同的问题域。五、为什么 epoll 思维在 DPDK 中会失效很多 Linux 开发者最熟悉的架构epoll ↓ 事件驱动 ↓ 业务处理这种模式在高并发服务器中非常成功。因为事件本身是稀疏的。例如连接建立 数据到达 连接关闭事件频率远低于 CPU 频率。而 DPDK 场景下情况完全不同。例如100G 网卡 64B 小包理论上超过 1 亿 PPS这意味着CPU 时时刻刻都在处理事件根本不存在等待。因此事件驱动开始失去意义。取而代之的是Polling六、为什么 DPDK 更像工厂流水线Linux Server 更像客服中心用户来了再处理没人来就等待。而 DPDK 更像高速流水线无论有没有任务机器都持续运转。因此Linux 关注响应速度DPDK 关注吞吐能力七、Linux 世界里状态很便宜在 Linux 服务器中维护状态非常简单。例如struct connection每个连接几十字节到几百字节。即使100万连接内存压力也不大。因此开发者习惯于到处存状态八、DPDK 世界里状态是昂贵资源在运营商数据面中情况完全不同。例如1000万 Session如果每个 Session1KB那么10GB 内存直接消耗掉。更严重的是CPU 每处理一个 Packet都要访问这些状态。于是真正的问题变成状态如何组织而不是状态如何存储九、为什么 Flow Table 比协议解析更重要很多新人学习 DPDK会花大量时间研究EthernetVLANIPv4IPv6TCPUDP实际上这些协议解析都属于固定成本真正影响系统性能的是Flow Lookup因为协议解析是顺序访问。而 Flow Lookup 往往涉及随机访问这才是数据面的核心难题。十、Linux 世界追求公平Linux 调度器的核心目标之一公平例如多个进程共享 CPU多个连接共享资源多个任务共享时间片。这是通用操作系统必须完成的使命。十一、DPDK 世界追求确定性数据面系统最害怕的不是慢。而是不稳定例如平均时延20us看起来很好。但如果P99 500us运营商就无法接受。因此DPDK 系统更关注确定性而不是公平性。十二、为什么 Linux 的共享思维会害死 DPDKLinux 编程中共享资源非常常见。例如全局连接表 全局缓存 全局状态因为系统主要受到 IO 限制。而 DPDK 系统中共享意味着同步同步意味着性能损失因此成熟数据面架构几乎都遵循Shared Nothing原则。十三、UPF 为什么天然适合 Shared-Nothing以 TEID 为例。可以按照TEID Hash分发到不同 Worker。例如Worker0 Worker1 Worker2 Worker3每个 Worker 维护自己的SessionPDRFARQER这样数据面完全不需要锁。十四、为什么控制面和数据面必须分离Linux 应用中配置变化通常不频繁。因此很多人喜欢直接修改共享结构。而数据面中这样做风险极大。因为Worker 正在处理百万 PPS 流量控制面同时修改状态很容易引发锁竞争Cache 抖动状态不一致因此成熟系统都会采用消息驱动而不是共享驱动十五、DPDK 的真正难点从来不是收发包很多人学习 DPDK 花大量时间研究rte_eth_rx_burst() rte_eth_tx_burst()事实上这些 API 一周就能掌握。真正困难的是Flow 管理状态管理多核架构控制面交互生命周期管理这些才是产品级系统的核心挑战。十六、从 Linux 工程师到数据面架构师很多开发者以为掌握 DPDK API就等于掌握了数据面开发。实际上真正需要转变的是思维方式。从连接思维转变为流量思维从请求处理转变为流量处理从共享资源转变为状态归属从公平调度转变为确定性执行十七、总结Linux 网络编程与 DPDK 数据面开发看似都在处理网络流量但两者关注的问题完全不同。Linux 世界关注的是连接 请求 用户DPDK 世界关注的是流量 状态 转发因此很多在 Linux 网络编程中被证明成功的经验在 DPDK 系统中并不一定成立。真正优秀的数据面开发者不仅需要理解协议和 API更需要完成一次思维模式的升级从连接思维 走向流量思维 从应用开发 走向数据面架构而这正是从普通 DPDK 开发者成长为数据面架构师的关键一步。