0. AIMD算法的简单回顾
(1) 慢开始阶段说明
开始时cwnd为1个最大报文段(MSS), 每当一个MSS收到确认, 则cwn增加1个MSS大小, 过程:
开始 ---> cwnd = 1
经过1个RTT后 ---> cwnd = 2*1 = 2
经过2个RTT后 ---> cwnd = 2*2= 4
经过3个RTT后 ---> cwnd = 4*2 = 8
可见, 慢开始, 实际上是指数增长的, 并不慢. 如果带宽为W,那么经过RTT*log2W时间就可以占满带宽, 但是,这个其实不是无限制的增长。
(2) 拥塞避免阶段(AIMD)
TCP使用了一个叫慢启动门限(ssthresh)的变量,当cwnd超过该值后,慢启动过程结束,进入拥塞避免阶段。对于大多数TCP实现来说,ssthresh的值是65536(同样以字节计算)。拥塞避免的主要思想是加法增大(additive increase),也就是cwnd的值不再指数级往上升,开始加法增加。此时当窗口中所有的报文段都被确认时,cwnd的大小加1,cwnd的值就随着RTT开始线性增加,这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值.
当出现拥塞的情况时: 把ssthresh降低为cwnd值的一半(multiplicative decrease), 把cwnd重新设置为1, 重新进入慢启动过程。
具体的伪代码如下:
nitially: cwnd = 1; ssthresh = infinite; New ack received: if (cwnd < ssthresh) /* Slow Start*/ cwnd = cwnd + 1; else /* Congestion Avoidance */ cwnd = cwnd + 1/cwnd; Timeout: /* Multiplicative decrease */ ssthresh = cwnd/2; cwnd = 1;
1. 在BDP下, 传统tcp的主要问题
(1) 效率问题: 传统tcp的AIMD的算法, 很难充分的利用带宽. 例子, MSS=1500-byte, RTT=100ms, 要达到10Gbps的带宽,拥塞窗口平均需要达到83333个MSS, 丢包率要达到5,000,000,000个MSS才丢一个, 如果从时间上说,要约1.6小时才丢一个,显然,这不现实。
上面例子的计算:
packet_size = 1500 byte
rtt = 100ms
throughput = 10Gbps
congestion_window=throughput*rtt/packet_size
发送的packet数目=throughput*rtt/packet_size=10*10^9*0.1/8/1500=83,333
根据拥塞窗口和丢包率p的关系: congestion_window=1.2/sqrt(p)
p=(1.2/congestion_window)^2=1/发送的总的包的数目
发送的总的包数=1/p=4,822,492,284 约 5,000,000,000个包才丢一个
发送5,000,000,000的时间5000000000/(83333*10)/3600=1.6h
一些tcp的计算公式:
R=RTT(s)
D=packet_size(bytes)
B=throughput (bps)
W=congestion window
得到:
W=BR/(8D)
W->1.2/sqrt(p)
根据丢包率: 1/p packets才丢一个包, 也就是1/(pW)个rtt才丢一个包(一个rtt可以发送W个)
RTTs Between Losses = 1/(pW)=1/[(1.2/W)^2*W]=W/1.5
也可以直接计算:
W=BR/(8D)
RTTs Between Losses = W/1.5=BR/12D
若R=0.1s, D=1500, 可以计算出一些示例:
TCP Throughput (Mbps) RTTs Between Losses W P
--------------------- ------------------- ---- -----
1 5.5 8.3 0.02
10 55.5 83.3 0.0002
100 555.5 833.3 0.000002
1000 5555.5 8333.3 0.00000002
10000 55555.5 83333.3 0.0000000002
(2) 公平性问题: 由于AIMD算法与RTT是相关的, 因此不可避免的存在不公平性, 即RTT小的链接会抢占更多的带宽.
tcp的性能随着丢包率和RTT的增大, 急剧的下降.
2. 已有的改进方法和缺点
(1) 修改AIMD算法, 使用大一点的增长参数, 小一点的减少参数. 例如: HighSpeed, Scalable, BiC, FAST, H-TCP, L-TCP. 但是这个难以部署, 开源的linux, 也要重新编译才能部署
(2) Parallel TCP, Rate-based reliable UDP, 主要用于私有网络, 其作用是最大可能的利用带宽, 实际使用时, 参数需要根据实际的网络进行调整, 适用场景较少.
3. udt
(1) 应用程序级别, 方便使用, 基于udp实现可靠传输,能充分利用带宽
(2) udt使用新的拥塞控制算法, 更好实现公平性.