TCP通信内核参数调优——拥塞窗口
2014-02-08 15:19:24   来源:我爱运维网   评论:0 点击:

1.背景 TCP是一个端到端(Peer-to-Peer)的传输层协议,处于应用层和网络层之间。在数据传输之前,由TCP模块在运行于不同主机上的两个...

1. 背景

      TCP是一个端到端(Peer-to-Peer)的传输层协议,处于应用层和网络层之间。在数据传输之前,由TCP模块在运行于不同主机上的两个应用程序之间建立直接连接,通常称为虚拟连接,其后的TCP报文在此连接的基础上进行传输。TCP协议在IP协议提供的服务基础上,提供面向连接的、可靠的、全双工的数据流传输服务。

    TCP协议通过动态的调整发送窗口的大小,来达到流量控制以及拥塞控制的目的。发送窗口的大小等于min(接收窗口的大小,拥塞窗口的大小)。若服务端需要传输给客户端的数据较大,则需要多次分块传输。即需要多个RTT时间才能完成数据的传输。显示接收窗口的大小和拥塞窗口的大小直接影响了完成所有数据传输的时间。理想情况下,如果接收端的处理能力足够强即接收窗口足够大,同时网络状况足够好即拥塞窗口足够大的话,可以一次性把所需传送的数据全部分片发给接收方。这样可以极大的减少网络传输耗时。

    linux 3.0以前,内核默认的initcwnd比较小,MSS为1460时,初始的拥塞控制窗口为3。linux3.0以后,采取了Google的建议,把初始拥塞控制窗口调到了10。具体的文章《 An Argument for Increasing TCP's Initial Congestion Window》。

    由于公司内部服务器之间的通信都是走专线的。网络状况足够好,根据业务需求,可以进一步调大拥塞窗口的初始值吗?

2. 拥塞窗口初始值调整案例分享

    对于公司内部的服务器一般情况下tcp连接的接收窗口的默认值为87380字节,最大值为 4194304。linux内核本身有一个缓冲大小自动调优的机制,接收窗口的实际大小会自动在最小值和最大值之间浮动,以期找到性能和资源的平衡点。具体参数的设置可以查看/proc/sys/net/ipv4/下的配置参数。但是发送方的拥塞窗口的初始值较小,一般是3。由于以太网的MSS为1460字节,那么就使得第一个包的大小最大只能为1460*3字节。

    以浏览器后台的抓取服务为例。抓取服务是浏览器后台实时抓取页面主资源及子资源的服务。抓取服务采用HTTP协议与部署在全国各地甚至是世界各地的WebServer进行数据传输,一旦抓取完成需要立即返回给前端调用者。实时抓取资源耗时越少,手机浏览器用户的体验也就越好。

为了缩短抓取服务与网站的通信耗时,通过自实现的智能路由服务,抓取服务的主调方会根据情况走专线调用其他区域的抓取服务从而使得抓取服务能够与网站就近通信。公司的跨区域专线的延迟时间大约是30ms左右。即当抓取服务的主调方走跨区域专线调用抓取服务时,走专线的耗时是不能忽略的。

    经统计,目前互联网上网页的内容99%在100K以内。所以浏览器这边的所有抓取服务所在机器的拥塞窗口的初始值都修改为了80。即尽量保证抓取服务一次就能把请求的URL的所有数据都发送给抓取的主调服务。这样修改的好处是,对于跨区域调用抓取服务时,由于同一个请求不需要多次通信,尽量一次网络传输就完成了响应,从而降低了抓取服务的响应数据的传送耗时。

    下图展示了普通情况下一次HTTP请求的耗时:

TCP通信内核参数调优——拥塞窗口

    由图中可知,一次请求总的耗时=连接建立时间+请求发送时间+等待响应时间+接收响应时间。连接时间等于1个RTT,因为发出了第三次握手的ACK后,马上就能触发发送真正的数据请求,并不用等待网站收到这个ACK。客户端发送请求的时间认为等于0。等待响应的时间,由于需要计算请求到达服务器的时间以及第一个响应包到达客户端的时间,所以等于1个RTT+服务端处理请求耗时。接收响应时间等于n个RTT,n大于等于0,若响应数据一次就发送完毕了,则按照我们的计算方式,n此时等于零。所以一次请求总的耗时=(n+2)RTT+服务端处理请求耗时。

通过调整拥塞窗口的初始值,可以使得n的取值尽量为0。

    通常内部服务器间通信是基于长连接的通信。当连接超过一定时间没有数据传输时,才断开连接。对于长连接,调整拥塞窗口的初始值有意义吗?

    查看服务器的/proc/sys/net/ipv4/目录下的tcp_max_ssthresh的值,发现tcp_max_ssthresh=0。这个值表示慢启动阈值。如果拥塞窗口的值cwnd小于阈值ssthresh,那么表示在慢启动阶段;如果拥塞窗口的值cwnd大于阈值ssthresh,那么表示在拥塞避免阶段,此时拥塞窗口cwnd不再像慢启动阶段那样呈指数级整整,而是趋向于线性增长,以期避免网络拥塞。

    所以对于我们的服务器,默认情况下,拥塞窗口会一直处于线性增长阶段,即增长非常慢。一旦出现丢包,拥塞窗口的值会减半。即在连接建立初期以及出现丢包后,拥塞窗口的值都会较小。从而使得传送的数据可能需要多次分块传输。

    综上所述,调整服务器的拥塞窗口的初始值是有意义的。不过,对于短连接的场景,拥塞窗口初始值的调整意义更大。但是注意,拥塞窗口的初始值值并不是越大越好。如果网络状态不太好的情况下,拥塞窗口的初始值设置的过大,可能会导致网络一直处于拥塞状态,适得其反。另一方面,网络中实际传输的未经确认的数据大小等于min(接收窗口的大小,拥塞窗口的大小),所以一旦接收方的接收窗口比较小的话,调整拥塞窗口的值也没什么作用。

3. 如何查看拥塞窗口初始值

    通过tcpdump抓取通信数据包。首先通过连接建立阶段的耗时确认RTT的值,然后计算第一个数据到达的时间加上一个RTT时间后,在这个时间段内收到的数据包的个数即为拥塞窗口的初始值。

相关热词搜索:TCP 通信 内核参数

上一篇:应该知道的Linux技巧
下一篇:最后一页

分享到: 收藏