
文章插图
Reno cwnd 图
6.2 CUBIC 算法CUBIC 算法和 Reno 算法区别主要在于慢启动和拥塞避免两个阶段 。因为 Reno 算法进入拥塞避免后每经过一个 RTT 窗口才加 1,拥塞窗口增长太慢,导致在高速网络下不能充分利用网络带宽 。所以为了解决这个问题,BIC 和 CUBIC 算法逐步被提了出来 。
(BIC 算法基于二分查找,实现复杂,不看了 。)
cubic 算法源码见 tcp_cubic 文件 。
6.2.1 CUBIC 算法原理

文章插图
cubic 窗口增长函数
CUBIC 的窗口增长函数是一个三次函数,非常类似于 BIC-TCP 的窗口增长函数 。CUBIC 的详细运行过程如下,当出现丢包事件时,CUBIC 同 BIC-TCP 一样,会记录这时的拥塞窗口大小作为 W max,接着通过因子 执行拥塞窗口的乘法减小,这里β是一个窗口降低常数,并进行正常的 TCP 快速恢复和重传 。从快速恢复阶段进入拥塞避免后,使用三次函数的凹轮廓增加窗口 。三次函数被设置在 W max 处达到稳定点,然后使用三次函数的凸轮廓开始探索新的最大窗口 。
CUBIC 的窗口增长函数公式如下所示:

文章插图
其中,*W(t)*代表在时刻 t 的窗口大小,C 是一个 CUBIC 的常量参数,t 是从上次丢包后到现在的时间,以秒为单位 。K 是上述函数在没有进一步丢包的情况下将 W 增加到 W max
经历的时间,其计算公式如下:

文章插图
其中β 也是常量(默认为 0.2) 。
6.2.2 Wmax 的更新

文章插图
static inline void bictcp_update(struct bictcp *ca, u32 cwnd, u32 acked){// ...if (ca->epoch_start == 0) {//丢包后,开启一个新的时段ca->epoch_start = tcp_jiffies32;/* record beginning */ca->ack_cnt = acked;/* start counting */ca->tcp_cwnd = cwnd;/* syn with cubic *///取max(last_max_cwnd , cwnd)作为当前Wmax饱和点if (ca->last_max_cwnd <= cwnd) {ca->bic_K = 0;ca->bic_origin_point = cwnd;} else {/* Compute new K based on* (wmax-cwnd) * (srtt>>3 / HZ) / c * 2^(3*bictcp_HZ)*/ca->bic_K = cubic_root(cube_factor* (ca->last_max_cwnd - cwnd));ca->bic_origin_point = ca->last_max_cwnd;}}//...}6.2.3 hystart 混合启动算法标准的慢启动在 BDP 网络环境下表现不好,不好的原因主要有两个:- 标准慢启动的拥塞窗口指数式的增长方式过于激进容易导致大量丢包,丢包恢复性能损耗太大 。在 ssthreshold 值设置的过高时,慢启动一段时间后,cwnd 的指数增长会显得过快 。有可能在上一个 RTT,cwnd 刚好等于 BDP;下一个 RTT,cwnd 就等于 2BDP 了 。这样就可能导致多出的一个 BDP 的数据包被丢弃 。这类丢包属于突发丢包(burst packet losses) 。
- 被优化过的慢启动机制,丢包时在数据包重传恢复的时候碰巧试图去减小服务器的负载,导致数据包恢复慢 。
Hystart 算法通过 ACK train 信息判断一个 Safe Exit Point for Slow Start.同时为了避免计算带宽,通过一个巧妙的转换(具体建议看论文),只要判断时间差是否超过 Forward one-way delay()来决定是否退出慢启动 。
Hystart 算法通过以下两个条件来判断是否应该退出慢启动 1.一个窗口内的数据包的总传输间隔是否超过 2. 数据包的 RTT sample(默认 8 个样本)是否出现较大幅度的增长 。如果前面 8 个样本中的最小 rtt 大于全局最小 rtt 与阈值的和,那么表示网络出现了拥塞,应立马进入拥塞避免阶段
6.3 BBR 算法
BBR 全称 bottleneck bandwidth and round-trip propagation time 。基于包丢失检测的 Reno、NewReno 或者 cubic 为代表,其主要问题有 Buffer bloat 和长肥管道两种 。和这些算法不同,bbr 算法会时间窗口内的最大带宽 max_bw 和最小 RTT min_rtt,并以此计算发送速率和拥塞窗口 。
6.3.1 BBR 算法原理如下图所示,当没有足够的数据来填满管道时,RTprop 决定了流的行为;当有足够的数据填满时,那就变成了 BtlBw 来决定 。这两条约束交汇在点 inflight =BtlBw*RTprop,也就是管道的 BDP(带宽与时延的乘积) 。当管道被填满时,那些超过的部分(inflight-BDP)就会在瓶颈链路中制造了一个队列,从而导致了 RTT 的增大 。当数据继续增加直到填满了缓存时,多余的报文就会被丢弃了 。拥塞就是发生在 BDP 点的右边,而拥塞控制算法就是来控制流的平均工作点离 BDP 点有多远 。
推荐阅读
- 如何基于TCP/IP协议进行MFC Socket网络通讯编程
- Treck TCP/IP协议库多个漏洞安全风险通告
- tcp,icmp,http 基于wireshark报文分析快速过滤报文时延
- 服务器海量TCP连接如何高效保活?
- 两万字深度介绍分布式,一文入魂
- TCP 半连接队列和全连接队列满了,怎么破?
- 说起来 TCP 的连接与释放真是个浪漫的故事呢!
- 网络安全常见协议解析:TCP、UDP、HTTP、FTP、SMTP等之间的区别
- 全网最强TCP/IP拥塞控制总结
- 轻松学习http知识让枯燥的内容变得生动有趣:TCP/IP四层模型
