tcp的拥塞窗口和慢启动

本文主要根据火丁笔记http://huoding.com/2013/11/21/299整理而成,详细信息请点击原文;

 

1 原理

流量控制rwnd

在每次交互时告知对端自己的接收窗口rwnd大小,避免接收缓冲溢出导致数据丢失;

 

慢启动cwnd

在得到发送方确认前,最大允许传输的未经确认的数据,主要为了避免耗尽网络流量。

cwnd无需通知给接收方,其初始值往往比较小,在达到阈值前呈指数级增长:假定当前cwnd=1,收到对端的ACK后变为2,若接下来发送的两个数据包又收到ack,则cwnd=4

慢启动阈值ssthresh:随着cwnd的增加,可能会导致网络过载即出现丢包,此时cwnd的大小会迅速衰减至当前的一半;

一旦触发了慢启动阈值,cwnd趋于线性增长,以避免再次迅速引发网络阻塞,直至下次丢包(如此反复)


 

两者关联

网络中实际传输的未经确认的数据大小 = min(rwnd, cwnd)

 
查看初始值

可通过perl脚本查看对端的初始设置https://github.com/redhands/initcwnd_check

# ./initcwnd_check.pl eth0 http://kr.yahoo.com/ 111.67.226.84

+ connected from x.x.x.x:2652 to 111.67.226.84:80

* kr.yahoo.com (111.67.226.84) - init_cwnd: 2 (2875 byte), init_rwnd: 4 (5840 byte)

 

调用ip route show会显示的本机各网卡接口的initcwndinitrwnd;

 


 

2  调优

2.1  调优rwnd

注:TCP使用16位来记录窗口大小,也就是说最大值是64KB,如果超过它,就需要使用tcp_window_scaling机制。

如果网络实际传输率远低于理论值,则可能是rwnd设置不合理造成的;

rwnd的合理值取决于BDP的大小,也就是带宽和延迟的乘积。假设带宽是 100Mbps,延迟是 100ms,那么计算过程如下:

BDP = 100Mbps * 100ms = (100 / 8) * (100 / 1000) = 1.25MB

此问题下如果想最大限度提升吞度量,接收窗口rwnd的大小不应小于 1.25MB

 

Linux有一个缓冲大小自动调优的机制,接收窗口的实际大小会自动在最小值和最大值之间浮动,以期找到性能和资源的平衡点。

shell> sysctl -a | grep mem

net.ipv4.tcp_rmem =

shell> sysctl -a | grep tcp_moderate_rcvbuf  

--1表示开启,tcp_rmem最大值设置为BDP0为关闭,tcp_rmem缺省值设置为BDP

 

除此之外,缓冲区还要保存TCP连接的元数据信息,相应开销为Buffer / 2^tcp_adv_win_scale

因此,rwnd合理值为BDP / (1 – 1 / 2^tcp_adv_win_scale)

 

 

2.2  调优cwnd

计算公式:cwnd = min(4 * MSS, max(2 * MSS, 4380))

以太网标准的MSS大小通常是1460,初始值为43803MSS

对于小的网络请求,譬如浏览器打开文本网页,cwnd越大则请求完成的越快,;

网络连接请求的内容越少,cwnd的影响就越明显,因为到达慢启动阀值前为指数增长,即便初始值很小也可迅速达到阀值;

至于initcwndGoogle给出的建议是10MSS,那么可以通过如下方法来调整initrwndinitcwnd

 

调整initrwnd & initcwnd

sajal@sajal-desktop:~$ sudo ip route change default via 192.168.1.1 dev eth0  proto static initrwnd 10

ajal@sajal-desktop:~$ ip route show

192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.100  metric 1

169.254.0.0/16 dev eth0  scope link  metric 1000

default via 192.168.1.1 dev eth0  proto static  initrwnd 10

 

sajal@sajal-desktop:~$ sudo ip route change default via 192.168.1.1 dev eth0  proto static initcwnd 10

sajal@sajal-desktop:~$ ip route show

192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.100  metric 1

169.254.0.0/16 dev eth0  scope link  metric 1000

default via 192.168.1.1 dev eth0  proto static  initcwnd 10

http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

注:这种方法在系统重启后会复原,可采用褚霸的stap脚本 
$ cat > tcp_init_cwnd.stp
probe kernel.function("tcp_init_cwnd").return
{
$return = $1
}
#设成7个mss
$ sudo stap -p4 -g -m initcwnd tcp_init_cwnd.stp 7
initcwnd.ko
#在系统的启动脚本里面运行以下命令:
$ sudo staprun -o initcwnd.out -D initcwnd.ko
#当然如果你的模块没有输出的话也可以直接, 这样更简单
$ sudo insmod initcwnd.ko
http://blog.yufeng.info/archives/1173 

 

代理服务器的设置
以CDN为例,如下图所示,其慢启动initcwnd决定了和客户端通信的下限,而接收窗口initrwnd决定了和服务器通信的下限;

因此对于类似CND之类的代理服务器,initcwnd和initrwnd都应该设置的尽量大一些;


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值