#2021年底大盘点#网卡 offload

不操千曲而后晓声,观千剑而后识器。这篇文章主要讲述#2021年底大盘点#网卡 offload相关的知识,希望能为你提供帮助。
随着单台服务器集成的计算能力的增长,服务器的带宽需求也同步提升,从10M到  100G,服务器的网络带宽提升速率远大于CPU的计算能力的增长速率。操作系统协议栈需要通过CPU来实现上层数据的封装和解封装,于是CPU的处理能力成为了网络传输能力的瓶颈。将由CPU处理的数据报文的分段、分片、校验等工作,交给网卡驱动来处理以降低CPU负担的相关技术(这里我们简称为网卡“offload特性”),是一种较好的提升服务器吞吐能力的方案。


1.    报文分片/重组相关概念
让我们从报文分片/重组处理相关的概念说起:
MTU  (Maximum Transmission Unit,最大传输单元)是指数据链路层支持上层协议最大一次传输的数据包大小(以字节为单位)。在以太网协议中缺省定义数据链路层的MTU为1500字节,这里的1500字节是包含IP头20字节在内的总长度,实际IP包中的载荷为1480字节。
MSS(Maximum Segment Size,最大报文长度),存在于TCP头的可选项中,是指在TCP连接建立时,收发双方协商通信时每一个报文段的最大报文长度。通常情况下,MSS小于等于(MTU-IP头长度(20字节)-TCP头长度(20字节))。在TCP通信建立连接时,TCP会取会话两端提供的MSS的最小值作为会话的MSS值。发送TCP报文时,双方会根据协商的MSS将TCP报文分段(Segmentation)。经过TCP分段处理后的IP包长度不会超过网卡的MTU,一般无需在IP层再做分片(Fragmentation)处理。
除了TCP报文有分段机制,其他协议的超大包(超过MTU的报文)基本都是由IP协议做分片处理的。当IP包长度大于数据链路层的MTU,首先根据IP头中的标记字段(Flags)中DF位判断数据包是否允许分片,如果数据包长度超过MTU且不允许分片,则直接被丢弃并向发包方发送错误消息;如果允许分片,则对数据包进行分片处理,保证分片后的每个数据包含IP头长度不超过MTU。分片后的数据包,会重新封装IP头,并在IP头中记录分片信息:

  • 在IP头的标识符(Identifier)中对于同一个被分片的数据包打上相同的标记;
  • ?标记字段(Flags)中标识是否为最后一个分片;
  • 记录分段偏移(Fragment Offset),保证分片报文能够被正确重组等。
2.    网卡offload技术
本文所描述的网卡的offload特性,主要思想是将原本由操作系统协议栈进行的TCP分段、IP分片、重组、校验等工作任务,移交给网卡驱动处理,在降低系统CPU消耗的同时,提升服务器的处理性能。从2012年开始,这项技术开始在普通用户的网卡上应用。随着技术的日趋成熟,目前越来越多的网卡设备开始支持offload特性,用以提升网络收发和处理的性能。常见的提升网卡发送/接收速率的offload技术包括  TSO、UFO、GSO、GRO等。
  • TSO  (TCP-Segmentation-Offload):将TCP分段工作交由网卡驱动执行,该特性需要网卡硬件支持。使能TSO后,操作系统可以将一个不超过64K字节(包含IP头长度和以太头长度在内)的任意大小的TCP报文传给网卡驱动,由网卡驱动层执行TCP分段、Checksum  计算和包头、帧头生成以及封装等工作,这样就消除了TCP分段工作带给CPU的负担。被TCP分段后的每个TCP Segment,都需要封装TCP头,TCP头部中有Checksum(校验和),因此TSO通常需要Checksum Offload支持,即由网卡驱动层同时完成TCP校验工作。
??
图1 TCP报文头部结构
  • UFO(UDP-Fragmentation-Offload):TSO针对TCP报文分段处理,UFO将对UDP报文进行IP分片的工作交由网卡驱动层处理。
  •   ?GSO相对TSO和UFO更为通用,可支持所有协议报文。GSO会首先确认网卡是否支持TSO,如果网卡支持且使能TSO,则将TCP分段交由网卡驱动层处理;否则由GSO在将报文发送给网卡驱动之前执行分片。GSO可以理解为TSO的补充。
  • LRO(Large-Receive-Offload):在接收网络数据时,网卡驱动层将接收到的TCP Segments在网卡驱动层执行报文重组,将合并后的大包传给操作系统。这样省去CPU在小包重组工作中的开销,提升服务器的接收效率。和TSO一样,LRO也需要网卡设备支持。LRO在做数据和信息合并时,因为收到信息有限,会出现合并后小包报文头中信息丢失等问题。鉴于LRO的局限性,一些网卡已经不再支持LRO。
  • GRO(Generic Receive Offload):GRO是与GSO相对的接收方特性。GRO不依赖物理网卡,支持更加丰富类型的协议报文。GRO运行在操作系统内核中,在做小包合并时掌握的信息较LRO更多,合并规则也更加严谨,避免了合并后数据信息丢失等问题,GRO已逐渐取代LRO。
3.    常用命令
offload状态查询命令:在Linux操作系统内,可以通过  ethtool -k  端口编号命令来查看网卡offload  选项的状态,
如:#ethtool -k eth0
….
tcp-segmentation-offload: on
                          tx-tcp-segmentation: on
                          tx-tcp-ecn-segmentation: off [fixed]
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
……
开启/关闭网卡offload命令:可通  ethtool -K  端口编号  gso off/on命令,按需使能或去使能网卡的offload功能。
如:#ethtool -k eth0 gso on
注意:修改网卡offload状态后,记得将命令行写入rc.local文件里,避免操作系统重启后,配置失效。
4.    网卡offload使用注意事项
网卡offload功能,对提升服务器转发性能方面功不可没。但是在实际情况中,并不是所有的场景下,都适合使能网卡的offload功能,下面就分享两个案例。
l  ?  ??案例一:通过LVS(Linux Virtual Server)负载均衡软件提供的VIP向FTP服务器上传文件失败。
经定位分析,出现上传文件失败的情况时,LVS服务器收到大量超过MTU的报文,由于LVS内核模块无法处理大于MTU的数据包,最终导致文件上传失败。在确认服务器的接入交换机侧未发送/接收到大于MTU的报文后,最终定位为LVS服务器网卡使能了GRO功能,LVS服务器侧网卡报文重组后出现大于MTU的数据报文导致问题。在操作系统内去使能GRO功能后,业务正常。
l  ?  ??案例二:分布式存储服务器物理网卡未使能GRO,聚合口(Bond口)使能GRO,导致上传文件MD5校验失败。
经定位分析,发送端在执行报文分片后,最后一个数据帧长度不足60字节,需要通过补零方式将数据帧长度补足60字节后发送。由于接收服务器侧物理口和聚合口GRO配置不一致,在GRO重组时未删除补零数据,报文重组后数据发生变化,文件损坏。修改物理网卡GRO和聚合口GRO配置一致后问题解决。
5.    综述
通常情况下,网卡Offload功能只要网卡支持,默认都是开启的。网卡Offload功能在提升服务器处理性能方面功不可没,但是在开启offload功能时,要分析服务器业务特性,按需开启。在处理大包导致业务异常等问题时,可以考虑优先排查网卡offload特性配置,如物理网卡和逻辑口(如聚合口)相关offload特性状态配置是否一致等;其次可通过修改offload状态尝试解决问题。
【#2021年底大盘点#网卡 offload】除了借助网卡的Offload特性提升服务器大包处理性能外,诸如RSS(Receive Side Scaling)等网卡驱动技术也在不失为一种不错的选择。在多核系统中,如果服务器网卡支持且使能了RSS,那么网卡将接收到属于同一个TCP连接的数据进程分成多个处理队列,分散给多个处理器或者物理核处理,从而有效提升处理器处理效率。

    推荐阅读