首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Mysql报文理解mtu拆包依据(tso/gro)

Mysql报文理解mtu拆包依据(tso/gro)

作者头像
mingjie
发布2022-05-12 09:47:31
发布2022-05-12 09:47:31
9750
举报

速查:

  1. tso在网卡层面拆包,gro在网卡层面拼包
    • ethtool -k eth0
    • generic-receive-offload:ethtool -K eth0 gso on
    • tcp-segmentation-offload:ethtool -K eth0 tso on
    • tcpdump -i eth0 -s 0 -w s3_s.cap port 3001
  2. 默认tso:on,gso:on,gro:on

1 mysql测试

client:172.16.12.233

server:172.16.12.219

网卡: 都是单卡eth0

测试过程:client上发1000字节的SQL到server,client上发超过1500字节的SQL到server

测试SQL超过1480:

代码语言:javascript
复制
很长的SQL超过了1480字节

抓包

代码语言:javascript
复制
tcpdump -i eth0 -s 0 -w s2_s.cap port 3006

1.1自建mysql结果

结论一

交互的包上都有DF标志,简单的说就是报文不允许切分,如果一定要切(路由觉得包太大只能丢弃)分直接返回失败,所以需要让client切好了再发。

The DF flag is typically set on IP packets carrying TCP segments. This is because a TCP connection can dynamically change its segment size to match the path MTU, and better overall performance is achieved when the TCP segments are each carried in one IP packet. So TCP packets have the DF flag set, which should cause an ICMP Fragmentation Needed packet to be returned if an intermediate router has to discard a packet because it’s too large. The sending TCP will then reduce its estimate of the connection’s Path MTU (Maximum Transmission Unit) and re-send in smaller segments. If DF wasn’t set, the sending TCP would never know that it was sending segments that are too large. This process is called PMTU-D (“Path MTU Discovery”). If the ICMP Fragmentation Needed packets aren’t getting through, then you’re dealing with a broken network. Ideally the first step would be to identify the misconfigured device and have it corrected; however, if that doesn’t work out then you add a configuration knob to your application that tells it to set the TCP_MAXSEG socket option with setsockopt(). (A typical example of a misconfigured device is a router or firewall that’s been configured by an inexperienced network administrator to drop all ICMP, not realising that Fragmentation Needed packets are required by TCP PMTU-D).

结论二

为什么MTU=1500但是wireshark看到的发包收包都有超过1500的呢?

原来在wireshark是在网卡层面以上抓的包,网卡根据tso和gro的配置自动拆/拼包,这两个概念后面介绍

2 TSO

查看参数配置:

代码语言:javascript
复制
ethtool -k eth0 | grep -E 'generic-segmentation-offload|tcp-segmentation-offload'

tcp-segmentation-offload: off
generic-segmentation-offload: on


# ethtool -K eth0 tso on
# ethtool -K eth0 tso off

为了降低 CPU 的负载,提高网络的出口带宽,TSO 提供一些较大的缓冲区来缓存 TCP 发送的包,然后由网卡负责把缓存的大包拆分成多个小于 MTU 的包。tcpdump 或者 wireshare 抓取的是网卡上层的包,所以我们可能会观察到大小超过 MTU 的包

  • generic-segmentation-offload必须打开后tso才能生效
  • tso关闭只需要关闭tcp-segmentation-offload

3 GRO

查看参数配置

代码语言:javascript
复制
ethtool -k eth0 | grep -E 'generic-receive-offload|large-receive-offload'

generic-receive-offload: off
large-receive-offload: off [fixed]

# ethtool -K eth0 gso off
# ethtool -K eth0 gso on

LRO 的核心在于:在接收路径上,将多个数据包聚合成一个大的数据包,然后传递给网络协议栈处理,但 LRO 的实现中存在一些瑕疵:

  • 数据包合并可能会破坏一些状态
  • 数据包合并条件过于宽泛,导致某些情况下本来需要区分的数据包也被合并了,这对于路由器是不可接收的
  • 在虚拟化条件下,需要使用桥接功能,但 LRO 使得桥接功能无法使用
  • 实现中,只支持 IPv4 的 TCP 协议

而解决这些问题的办法就是新提出的 GRO(Generic Receive Offload)

首先,GRO 的合并条件更加的严格和灵活,并且在设计时,就考虑支持所有的传输协议,因此,后续的驱动,都应该使用 GRO 的接口,而不是 LRO,内核可能在所有先有驱动迁移到 GRO 接口之后将 LRO 从内核中移除。

而 Linux 网络子系统的维护者 David S. Miller 就明确指出,现在的网卡驱动,有 2 个功能需要使用,一是使用 NAPI 接口以使得中断缓和 (interrupt mitigation) ,以及简单的互斥,二是使用 GRO 的 NAPI 接口去传递数据包给网路协议栈。

在 NAPI 实例中,有一个 GRO 的包的列表 gro_list,用堆积收到的包,GRO 层用它来将聚集的包分发到网络协议层,而每个支持 GRO 功能的网络协议层,则需要实现 gro_receive 和 gro_complete 方法。

参考

https://www.ibm.com/developerworks/cn/linux/l-cn-network-pt/index.html

http://wsfdl.com/%E8%B8%A9%E5%9D%91%E6%9D%82%E8%AE%B0/2016/07/12/tcp_package_large_then_MTU.html

https://liqiang.io/post/tcp-segmentation-offload-introduction-and-operation-2f0b8949

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 mysql测试
    • 1.1自建mysql结果
      • 结论一
      • 结论二
  • 2 TSO
  • 3 GRO
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档