车小胖谈网络:MTU 与 MSS

来源:互联网 发布:什么软件看小说免费 编辑:程序博客网 时间:2024/05/23 07:26
作者:车小胖
链接:https://zhuanlan.zhihu.com/p/21268782
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

MTU: Maximum Transmit Unit,最大传输单元,即物理接口(数据链路层)提供给其上层最大一次传输数据的大小,比如IP层、MPLS层等等,因为目前应用最多的接口是以太网,所以谈谈以太网口的MTU,假定其上层协议是IP,缺省MTU=1500,意思是:整个IP包最大从这个接口发送出去的是1500个字节。可以通过配置修改成更大或更小的值,只要在系统的边界值以内即可,但是切记要在链路的两端都要修改,而且要大小一样,如果不一样,会造成大侧的数据被小侧丢弃!

MSS:Maximum Segment Size ,最大TCP分段大小,不包含TCP头和 option,只包含TCP Payload ,TCP用来限制自己每次发送的最大分段尺寸。

网络通信,尽一切可能避免IP的分片!为什么?因为负责IP分片的那台主机、路由器会花费很多CPU资源来处理分片,同时负责重组IP分片的主机、路由器则需要更多的CPU资源来重组这些IP包的分片。

曾经在实验室里做过实验,比如一台路由器的数据处理能力是10G,如果处理分片则降低到2G左右,这种对比是基于同样大小的IP报,这还是比较高端的平台,采用硬件,软件CPU一起协作才达到的水平,如果比较低端的平台,纯粹采用CPU软件来处理,那数据包处理能力更是惨不忍睹!

另外这个数据的对比只是给大家一个直观的感受,在现实应用中还是基于不同厂商、不同平台,拿到准确的datasheet,拿到准确的分片性能数据。

正是因为分片对系统的性能影响颇大,TCP/IP协议的创造者们知道这一点,那就是避免IP分片,于是采用了各种措施来避免:

1)Maximum Segmeant Size

一般网络接口都有一个最大传输单元即MTU,比如MTU=1500,什么意思呢?如果IP包的尺寸<=1500,原封不动从这个网络接口发送,否则就需要分片。那聪明的你一定会说,既然知道MTU=1500,那为什么要发超过1500的包呢?给自己找不自在?既然IP包最大1500了,那如果TCP=1480不就可以了吗?

IP = IP Header + TCP = 20 + 1480 = 1500

TCP = TCP Header + TCP Payload = 20 + 1460 = 1480

这个TCP Payload = 1460 对应的就是TCP最大传输单元,我们称之为“ Maximum Segment Size" 即MSS,那么MSS= MTU - IP Header - TCP Header =1500 - 20 -20 =1460。TCP 在三次握手的第一个SYN消息中有一个选项option 4,通告双方的MSS,如果一方MSS=1460,而另一方的MSS=8960,会选择较小的一方即1460作为这个TCP连接的MSS:

MSS =minimum{MSSs ,MSSr}

则 MSS = 最小值 { 1460,8960 }= 1460

这样双向通信都可以避免因为IP包太大引起的分片。但是MSS能完全避免IP分片吗?不能!



为什么MSS不能避免分片?

记住一点MSS只是解决源主机、目的主机第一跳first hop MTU问题,这样保证第一跳不分片,但是这种方式不能克服路径中有更小的MTU而造成的分片。

那还有什么好的办法?



2)Path MTU Discovery 即 传输路径MTU的发现

还是拿第一个例子来讲,IP包= 1500,从源主机发送出来了,然后在互联网上一跳一跳奔向目的地,突然到了一台路由器上,需要从一个接口发送出去,这个接口MTU只有1000,由于IP包 1500 >1000,这个IP包必须分片才能出去,于是就分成了两个IP分片发送出了,那能否让这台路由器不分片呢?可以的,大家记得IP头有一个标志位DF,Dont Fragment,如果为1,意思是这个IP包在传输的过程中不能分片,如果此IP包大于物理接口的MTU,请直接丢弃,并发消息告诉源主机!什么消息?ICMP的消息,告诉包因为太大了,因为不能分片所以被丢了,并告诉源主机可以重新发小于等于MTU的包;那发什么样的ICMP消息?

ICMP协议里有type字段,还有code字段,发送type=3,code=4,MTU=1000的消息就可以了,当这个ICMP消息到达IP包的源主机,源主机知道原来是IP太大了,那最大可以发送多大的呢?ICMP消息里有,那就是MTU=1000,于是源主机发送小于等于1000字节的就可以避免在传输路径上的分片。那读者可能会说,如果IP包=1000在传输过程中遇到更小的MTU=500怎么办?呵呵,重复以上的步骤就可以了!

有细心的读者会说,如果ICMP type=3 code=4无法到达源主机会发生什么?很显然IP包被静静地丢了,TCP连接超时中断。ICMP为什么回不来?一般被防火墙或者路由器的访问控制列表ACL给无情拒绝通过!如果你可以管理配置这些设备,只要允许ICMP type=3 code=4通过就可以了,否则只有老老实实关闭 Path MTU Discovery 这个功能了,至少分片可以通信,而不分片则彻底无法通信了,这就是聊胜于无,无奈的选择!



源主机的IP包被丢弃谁来重传?

如果是UDP的应用,由application 来重传。如果TCP session,由TCP来重传

先明确这个前提,再来分析这个因为IP包太大被中途丢弃所引起的一系列动作

1) IP 1500 > RouterX 出接口MTU 1000,DF=1,于是RouterX丢弃,并发送ICMP给source host,type=3,code=4,在ICMP消息里还包含了五元组:Source IP,Destination IP,Source Port,Destination Port,IP协议号:6,即TCP,还有一个关键消息,即RouterX 出接口MTU的值,即这里的1000。


2)假定ICMP很幸运到达了 source host,IP层解开这个包,得到

a) 五元组

b) RouterX MTU =1000


IP通过五元组知道这是哪个TCP连接,即刻修改 [Source IP, Destination IP] 这条路径的PMTU值=1000,IP层给TCP session发送两个通知

a) 包被丢失

b) PMTU 变小到1000

当TCP session知道包被丢失,先发送重传队列,很显然还是会被丢弃,当接收到到PMTU变小到1000的通知消息时,相应修改MMS_S= 980(maximumsend transport-message size, 包含TCP头 ),对新生成的TCP Segment则使用960字节,最终IP包为1000字节。


3) TCP Adjust-MSS

有时企业网的设计者为了怕引起在传输路径上的分片,采用这个feature,比如在分公司出口网关WAN接口上使用此feature,检查TCP SYN消息里的option 4,即MSS,可以将双向的MSS修改成更小的值,比如1380,这样即使这个IP包可能会通过GRE Tunnel,IP security VPN Tunnel,会被加上几十个字节的新的IP头信息,GRE Tunnel头信息也不会分片。

此feature 只对TCP连接有用,不适用UDP应用!另外这个feature是cisco 私有的实现,不是标准,这里把它拎出来也是加深对MSS得理解。


谈完以上话题,再谈谈二层交换机,交换机接口下也有MTU,缺省值一般为1500,如果有一个帧1600字节需要从这个发出去,会发生什么?一般直接丢,会不会发什么ICMP消息出来?不会的!那如果1508字节的帧呢?转发还是丢弃?我们称这种帧为baby giant 帧,即比1500大那么一点的帧,一般是加入了MPLS label造成的,具体到不同的产品有不同的动作,有直接丢的,也有原封不动继续转发的,提到这些只是提供一些参考,不具有太现实得意义,我切说,你且听,具体到特定的平台,有这些概念在心中,会有一个提前的准备。



为什么数据中心常用 > 8192字节的MTU?

曾经在实验室里做过实验,把一台路由器设备的进出接口MTU=9218,然后用各种尺寸的包打流量,来测试系统数据throughput, 结果证明,包越大,系统得吞吐量越大,也就是传输效率越高。所以用更大的MTU可以提供更高的数据传输能力。

NFS网络服务器之间的数据读取、存储最小单位是磁盘扇区,而服务器扇区经常使用8192这个值,而且为了避免被分片,发送这些扇区数据的IP包的DF设置为1,意思是不允许分片,那最好的办法就是提供数据中心全网的MTU>8192,由于还要考虑IP 头,UDP头,文件系统头,一般选择9000左右足够用的了。

0 0