减少包头处理开销最直接的方法:减少数据包数量

背景
目前,有大量的网络应用在处理数据包的时候只需要处理数据包头,而不会操作数据负载部分,例如防火墙、tcp/ip协议栈和软件交换机。对这类网络应用而言, 包头处理产生的开销(称为“per-packet overhead”)占了整体开销的大部分。因此,如何减少包头处理开销是优化这类应用性能的关键。
减少包头处理开销最直接的方法:减少数据包数量
如何减少包数量?
增大maximum transmission unit (mtu)。在数据量一定的情况下,使用大mtu的数据包可携带更多数据,从而减少了包的总量。但mtu值依赖于物理链路,我们无法保证数据包经过的所有链路均使用大mtu。
利用网卡特性:large receive offload (lro),udp fragmentation offload (ufo)和tcp segmentation offload (tso)。如图1所示,lro将从物理链路收到的tcp包(如1500b)合并为长度更长的tcp包(如64kb);ufo和tso将上层应用发送的长数据负载的udp和tcp包(如64kb)拆分成长度更短的数据包(如1500b),以满足物理链路的mtu限制。通过在网卡上进行包合并和拆分,在不需要任何cpu开销的情况下,上层应用就可以处理数量大大减少的大包。然而,lro、tso和ufo通常只能处理tcp和udp包,而且并非所有的网卡都支持这些特性。
软件包合并 (generic receive offload,gro)和包拆分 (generic segmentation offload,gso)。与前两种方法相比,gro和gso有两个优点:第一,不依赖于物理链路和网卡;第二,能够支持更多的协议类型,如vxlan和gre。
图1. lro、ufo和tso工作原理
为了帮助基于dpdk的应用程序(如open vswitch)减少包头处理开销,dpdk分别于17.08和17.11支持了gro和gso。如图2所示, gro和gso是dpdk中的两个用户库,应用程序直接调用它们进行包合并和分片。
图2. dpdk gro和dpdk gso
1
gro库和gso库结构
图3描绘了gro库和gso库的结构。根据数据包类型,gro库定义了不同的gro类型。每一种gro类型负责合并一种类型的数据包,如tcp/ipv4 gro处理tcp/ipv4数据包。同样的,gso库也定义了不同的gso类型。gro库和gso库分别根据mbuf的packet_type域和ol_flags域将输入的数据包交给对应的gro和gso类型处理。
图3. gro库和gso库的框架
2
如何使用gro库和gso库?
使用gro和gso库十分简单。如图4所示,只需要调用一个函数便可以对包进行合并和分片。
图4. 代码示例
为了支持不同的用户场景,gro库提供了两组api:轻量模式api和重量模式api,如图5所示。轻量模式api应用于需要快速合并少量数据包的场景,而重量模式api则用于需要细粒度地控制合包并需要合并大量数据包的场景。
图5. 轻量模式api和重量模式api
3
dpdk gro的合包算法
算法挑战
在高速的网络环境下,高开销的合包算法很可能会导致网卡丢包。
包乱序(“packet reordering”)增加了合包难度。例如linux gro无法合并乱序的数据包。
这就要求dpdk gro的合包算法:
足够轻量以适应高速的网络环境
能够合并乱序包
基于key的合包算法
为解决上述两点挑战,dpdk gro采用基于key的合包算法,其流程如图6所示。对新到的数据包,首先按照流(“flow”)对其进行分类,再在其所在的流中寻找相邻的数据包(“neighbor”)进行合并。若无法找到匹配的流,就插入一条新流并将数据包存储到新流中。若无法找到邻居,则将数据包存储到对应的流中。
基于key的合包算法有两个特点。首先,通过流分类来加速数据包的合并是十分轻量的一种做法;其次,保存无法合并的数据包(如乱序包)使得之后对其进行合并成为可能,故减轻了包乱序对合包带来的影响。
图6. 基于key的合包算法流程
例如,tcp/ipv4 gro使用源和目的ethernet地址、ip地址、tcp端口号以及tcp acknowledge number定义流,使用tcp sequence number和ip id决定tcp/ipv4包是否为邻居。若两个tcp/ipv4的数据包能够合并,则它们必须属于同一个流,并且tcp序号和ip id必须连续。
4
dpdk gso的分片策略
分片流程
如图7所示,将一个数据包分片有3个步骤。首先,将包的数据负载分成许多长度更小的部分;其次,为每一个数据负载部分添加包头(新形成的数据包称为gso segment);最后,为每个gso segment更新包头(如tcp sequence number)。
图7. gso分片流程
gso segment的结构
生成一个gso segment的最简单方法就是拷贝包头和数据负载部分。但频繁的数据拷贝会降低gso性能,因此,dpdk gso采用了一种基于零拷贝的数据结构——two-part mbuf——来组织gso segment。如图8所示,一个two-part mbuf由一个direct mbuf和多个indirect mbuf组成。direct mbuf用来存储包头,indirect mbuf则类似于指针,指向数据负载部分。利用two-part mbuf,生成一个gso segment仅需拷贝长度较短的包头,而不需要拷贝较长的数据负载部分。
图8. two-part mbuf的结构
gro库和gso库的状态
目前,gro库还处于一个初期阶段,仅对使用最广泛的tcp/ipv4数据包提供了合包支持。gso库则支持更丰富的包类型,包括tcp/ipv4、vxlan和gre。

电子元件氧化发黑怎么处理
丁渭滨加入芯行纪,领衔开展EDA技术研发创新
手机的NFC功能到底有什么用处呢?能不能复制小区的门禁卡
基于TSN的融合网络的四大优势
开发能够在AR/VR设备中准确预测头部方向的算法
减少包头处理开销最直接的方法:减少数据包数量
过滤式手柄焊接球阀产品性能特征
二次回流焊无铅焊锡膏解决方案
关于Oculus Go,卡马克主要谈了五点
iPhone8什么时候上市最新消息:iPhone8真机曝光!八曲面屏+全虚拟键+性能逆天,你不买吗?
区块链基础设施先锋“Splend”独特定位解决区块链问题
特斯拉大跌14% 持有特斯拉股票风险太大
边缘计算驱动5G网络与各领域新技术的发展,实现了5G能力的进一步延伸
有害气体消毒除菌装置废气消毒除菌装置
AR领域的最新技术和突破有助于智能眼镜市场发展
qled和led有啥区别
OP-TEE的安全存储的简介
兆芯 双路32核 雷神全新博睿FX2服务器亮相
彩电行输出变压器输出电压是多少
DFRobot最新推出Gadgeteer扩展板介绍