• TCP传输的数据大小大于MTU(1500)


    一、redis写入数据

    public class JedisDemo {
        static String host = "192.168.91.128";
        static int port = 6379;
        
        public static void main(String[] args) throws Exception {
            try (JedisPool jedisPool = new JedisPool(host, port)) {
                Jedis jedis = jedisPool.getResource();
                StringBuilder sb = new StringBuilder();
                for (int i = 1; i < 10000; i++) {
                    sb.append(i);
                }
                String trueString = sb.toString();
                System.out.println(trueString.getBytes().length);//长度为38889
                jedis.set("thisiskey", sb.toString());
            }
        }
    }
    

    一次性向redis中写38889字节的数据。

    接下来通过抓包来看redis是tcp是如何传输这些数据的。

    二、抓包redis网络交互数据

    在redis服务器抓包

    tcpdump -w redis_dump.cap -i eth0
    

    打开dump

    可以看到握手后本机向redis服务器分别传输了两次数据,大小分别为14654字节和24345字节。

    初看这里是不对的,为什么呢?

    因为以太网链路层的最大传输单元(MTU:Maximum Transmission Unit)是1500字节。

    上面抓的包里面每次传输的数据是10倍的MTU,明显是不合理的。

    问题出在哪里?

    难道一次的传输数据会超过MTU的限制?

    三、网卡TSO和GRO

    先说结论:每次传输的数据量大小是不会超过MTU的限制的

    这就类似于路只有一米宽,那么最多也就允许一米的车行驶。无论如何都不可能有超过1米的车在上面行驶。

    那么为什么会抓包抓到远远大于MTU的包呢?

    这里需要引入两个概念:TSO和GSO(linux默认是打开的)

    3.1 TSO

    TSO(TCP Segmentation Offload)

    把TCP分段的过程直接移到网卡中进行,当发送的机器网卡支持TSO时,TCP层不再对大于MSS的数据进行分片,而是直接把数据传送到网卡,由网卡渠道进行分片,从而避免在TCP分片而占用CPU。

    1. 数据拆分所需要的CPU开销挪到网卡
    2. 实际在链路层还是按照MTU进行传输

    TSO示意图:

    这个需要在请求发送的机器上进行抓包验证(本文没有实际操作)。

    3.2 GRO(LRO)

    Generic Receive Offload(Large Receive Offload)

    在网卡驱动层面将受到的多个数据包聚合成一个大的数据包,一次性交给上层传输层,减少上层协议栈对应的CPU的开销。

    LRO示意图:

    这个需要在接受请求的机器进行抓包验证,本文的例子就是基于接受请求的机器抓包而演示的。

    3.3 关闭GRO后再次抓包

    关闭redis服务器的GRO。

    ethtool -K eno1  gro off
    

    再次在redis服务器抓包。

    可以看到每次的传输都变成了1514字节,其中数据为1500字节,和MTU的大小一样。

    【参考】:http://www.slideshare.net/eurobsdcon/20140928-gso-eurobsdcon2014

    作者:iBrake
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    基于p2p聊天室的原理介绍.个人学习笔记
    一个可移植数据库操作组件的简单介绍
    常见任务
    sql常用语句
    认真写写SQLAlchemy
    Jenkins 安装与使用手册
    Ajax
    支持主流注册中心,SolarMesh发布新版本 SolarMesh
    API标准化对Dapr的重要性
    企业数字化转型,你知道有哪些关键要素吗?
  • 原文地址:https://www.cnblogs.com/Brake/p/14502879.html
Copyright © 2020-2023  润新知