DPDK是intel推出的高效的zero-copy的发包工具,许多同学对其中的关键技术并不太了解,这里罗列一些粗略的技术点,感兴趣的可以针对其中某些点深入研究。
补充一点,intel最近推的SPDK跟DPDK类似,SPDK是跨设备IO,SPDK更复杂,需要考虑读写冲突、IO调度和不同硬件特性的优化(后面有时间研究下)。这里单说DPDK的技术
- 用户态驱动实现zero-copy。如果使用linux内核的协议栈发包,会多一次用户态到内核态的内存数据copy。linux内核已经支持用户态驱动的framework,编写用户态驱动可以减少内存copy
- 传统的linux网卡驱动是基于cpu中断方式,内核发送线程首先将数据copy到发送缓冲区后自己进入睡眠,网卡驱动程序将缓冲区数据发送完毕后,会给cpu一个中断信号,cpu在中断处理程序中将发送线程从睡眠中唤醒。这就导致了大量的cpu中断,特别虚机的场景通过软中断方式进行模拟,高并发的场景会导致cpu利用率很高。DPDK的做法是,在缓冲区头部有一个标记位,记录该缓冲区数据发送的状态,驱动程序发送完数据后,将缓冲区的标记为置为空闲,然后有一个polling线程不断去检测该标记为,检测发送成功后就会回收内存并做相应的回调处理。这样就减少了CPU的中断次数。
- 高速发包需要大量的申请和回收内存缓冲区,需要一个高效的内存池管理,算法和数据结构有很多,需要根据实际的应用场景择优选择
- ring buffer,环形队列。发送者和接收者的需要一个无锁的结构提高并发的效率。简单的环形队列支持一个读者一个写着,多个生产者和消费者的工作队列学术界和工业界也有现成的成果和实现。
DPDK并没有实现一个完整的TCP/UDP/IP的协议堆栈,这点需要开发者自己来实现。