《TCP/IP详解》卷1第16章 TCP拥塞控制&&BBR分析

Posted 小麦China

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《TCP/IP详解》卷1第16章 TCP拥塞控制&&BBR分析相关的知识,希望对你有一定的参考价值。

在TCP的演进过程中,出现了很多优秀的思想和算法,以实现网络传输过程中,在公平竞争性的前提下,尽可能地利用带宽资源。本文介绍TCP发展过程中出现的几种拥塞控制算法。

需要解决的问题:检测、控速、重传

  • 检测:丢失超时、3个冗余ACK、网络反馈、延迟变化
    • Tahoe、Reno、New Reno、SACK算法,基于事件,基于丢包,超时、3个冗余ACK,网络已经出现拥塞,反应慢
    • ECN,基于网络显式反馈,网络反馈
    • 延迟变化,基于RTT
  • 控速:
  • 重传:重传的时机和对象

拥塞控制前言

1、公平性

公平性是在发生拥塞时各源端(或同一源端建立的不同TCP连接或UDP数据报)能公平地共享同一网络资源(如带宽、缓存等)。处于相同级别的源端应该得到相同数量的网络资源。产生公平性的根本原因在于拥塞发生必然导致数据包丢失,而数据包丢失会导致各数据流之间为争抢有限的网络资源发生竞争,争抢能力弱的数据流将受到更多损害。因此,没有拥塞,也就没有公平性问题。

TCP层上的公平性问题表现在两方面:

(1)面向连接的TCP和无连接的UDP在拥塞发生时对拥塞指示的不同反应和处理,导致对网络资源的不公平使用问题。在拥塞发生时,有拥塞控制机制的TCP会按拥塞控制步骤进入拥塞避免阶段,从而主动减小发送到网络的数据量。但对无连接的数据报UDP,由于没有端到端的拥塞控制机制,即使网络出现了拥塞,也不会减少向网络发送的数据量。结果遵守拥塞控制的TCP数据流得到的网络资源越来越少,没有拥塞控制的UDP则会得到越来越多的网络资源。

(2)TCP连接之间也存在公平性问题。产生问题的原因在于使用了不同的拥塞控制算法,一些TCP在拥塞前使用了大窗口尺寸,或者它们的RTT较小,或者数据包比其他TCP大,这样它们也会多占带宽。

主要四个过程

1)慢启动;2)拥塞避免;3)拥塞发生,快重传;4)快速恢复。

经典概念

  1. RTT:数据包从发出去到收到对它的ack的来回时间,采用平滑方式计算RTT
  2. RTO:重传超时。简单的如RTO=n*RTT, n=3(或其他RTO计算方法)
  3. SACK:TCP Option携带多组ACK信息
  4. FR:Fast Retransmission,收到3个dup ack后,即可认为发生了丢包。不需要等待RTO超时即可重传丢失的包。
  5. ER:Early Retransmission,无法产生足够的dupack和没有新的数据包可以发送进入网络的情况下,减少触发FR的dup ack数量,以达到触发FR的目的。
  6. TLP:如果发生了尾丢包,由于尾包后面没有更多的数据包,也就没有办法触发任何的dupack。实际上,Google统计超过70%的RTO是尾丢包导致没有任何dup ack。TLP算法是通过发送一个loss probe包,来产生足够的SACK/FACK的信息以触发RF。
  7. Pacing:控制发送速率,防止bursting
  8. 流量控制:Flow control站在单条TCP连接的维度,目的是让发送方发包的速度,不超过接收方收包的能力。所以流控解决的问题是,如何在接收方可承受的范围内,让单条 TCP 连接的速度最大化。通过滑动窗口机制实现。
  9. 拥塞控制:Congestion control站在整个互联网的维度,让网络里所有TCP连接最大化共享网络通道的同时,尽可能的少出现网络拥塞现象,让网络世界里的每一个参与者既公平又高效。
  10. cwnd:发送窗口,拥塞窗口;在拥塞控制过程中窗口大小值变化。
  11. rwnd:接收窗口,通知发送者能够发送的数据大小。
  12. sliding window:滑动窗口,只是一种抽象机制概念;在发送请求及收到ack的过程中滑动。

TCP拥塞控制算法分类

1、基于丢包的拥塞控制:Tahoe、Reno、New Reno

因为Reno等算法是后续算法的基础,这里详细的描述下Reno算法的过程。

(1)慢热启动算法 – Slow Start

  • 连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据。
  • 每当收到一个ACK,cwnd++; 呈线性上升。
  • 每当过了一个RTT,cwnd = cwnd*2; 呈指数让升。
  • 还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”。

(2)拥塞避免算法 – Congestion Avoidance

当cwnd >= ssthresh时,就会进入“拥塞避免算法”。算法如下:

  • 收到一个ACK时,cwnd = cwnd + 1/cwnd
  • 当每过一个RTT时,cwnd = cwnd + 1

(3)拥塞状态算法 – Fast Retransmit

Tahoe是等RTO超时,FR是在收到3个duplicate ACK时就开启重传,而不用等到RTO超时。拥塞发生时:

  • cwnd = cwnd /2
  • sshthresh = cwnd

(4)快速恢复 – Fast Recovery

  • cwnd = sshthresh + 3 * MSS (3的意思是确认有3个数据包被收到了)
  • 重传Duplicated ACKs指定的数据包
  • 如果再收到 duplicated Acks,那么cwnd = cwnd +1
  • 如果收到了新的Ack,那么,cwnd = sshthresh ,然后进入拥塞避免算法。

Reno算法以其简单、有效和鲁棒性,应用最广泛。该算法所包含的慢启动、拥塞避免和快速重传、快速恢复机制,是现有的众多算法的基础。

从Reno运行机制中很容易看出,为了维持一个动态平衡,必须周期性地产生一定量的丢失,再加上AIMD机制--减少快,增长慢,尤其是在大窗口环境下,由于一个数据报的丢失所带来的窗口缩小要花费很长的时间来恢复,这样,带宽利用率不可能很高且随着网络的链路带宽不断提升,这种弊端将越来越明显。另外,丢包并不一定是网络拥塞,可能是网络常态,但是基于丢包的拥塞控制并不能区分。

2、基于时延RTT的带宽预测:vegas

vegas通过对RTT的非常重的监控来计算一个基准RTT。然后通过这个基准RTT来估计当前的网络实际带宽,如果实际带宽比我们的期望的带宽要小或是要多的活,那么就开始线性地减少或增加cwnd的大小。

中间路由器缓存数据导致RTT变大,认为发生拥塞;RTT不公平性,当不同的数据流对网络瓶颈带宽进行竞争时,具有较小RTT的TCP数据流的拥塞窗口增加速率将会快于具有大RTT的TCP数据流,从而将会占有更多的网络带宽资源。

3、基于丢包和RTT:westwood

在发送端做带宽估计,当探测到丢包时,根据带宽值来设置拥塞窗口、慢启动阈值。 那么,这个算法是怎么测量带宽的?每个RTT时间,会测量一次带宽,测量带宽的公式很简单,就是这段RTT内成功被ACK了多少字节。Westwood会根据RTT变化来判断丢包是否是网络拥塞造成的,还是网络常态的丢包。如果时延变化不明显,就认为是非网络拥塞,此时cwnd减少的比较小。

4、二分搜索最佳cwnd:BIC-TCP

BIC-TCP是Linux 2.6.18默认拥塞控制算法,依赖丢包条件触发。BIC-TCP认为TCP拥塞窗口调整的本质就是找到最适合当前网络的一个发送窗口,为了找到这个窗口值,TCP采取的方式是(拥塞避免阶段)每RTT加1,缓慢上升,丢包时下降一半,接着再来慢慢上升。BIC-TCP的提出者们看穿了事情的本质,其实这就是一个搜索的过程,而TCP的搜索方式类似于逐个遍历搜索方法,可以认为这个值是在1和一个比较大的数(large_window)之间,既然在这个区间内需要搜索一个最佳值,那么显然最好的方式就是二分搜索思想。

BIC-TCP就是基于这样一个二分思想的:当出现丢包的时候,说明最佳窗口值应该比这个值小,那么BIC就把此时的cwnd设置为max_win,把乘法减小后的值设置为min_win,然后BIC就开始在这两者之间执行二分思想--每次跳到max_win和min_win的中点。

BIC-TCP 算法仿真曲线 

BIC也具备RTT的不公平性。RTT小的连接,窗口调整发生的速度越快,因此可能更快的抢占带宽。

5、连续拥塞间隔:CUBIC

CUBIC在设计上简化了BIC-TCP的窗口调整算法,在BIC-TCP的窗口调整中会出现一个凹和凸(这里的凹和凸指的是数学意义上的凹和凸,凹函数/凸函数)的增长曲线,CUBIC使用了一个三次函数(即一个立方函数),在三次函数曲线中同样存在一个凹和凸的部分,该曲线形状和BIC-TCP的曲线图十分相似,于是该部分取代BIC-TCP的增长曲线。另外,CUBIC中最关键的点在于它的窗口增长函数仅仅取决于连续的两次拥塞事件的时间间隔值,从而窗口增长完全独立于网络的时延RTT,使得连接之间保持良好的RRTT公平性。

来看下具体细节:当某次拥塞事件发生时,Wmax设置为此时发生拥塞时的窗口值,然后把窗口进行乘法减小,乘法减小因子设为β,当从快速恢复阶段退出然后进入到拥塞避免阶段,此时CUBIC的窗口增长开始按照“凹”式增长曲线进行增长,该过程一直持续直到窗口再次增长到Wmax,紧接着,该函数转入“凸”式增长阶段。该方式的增长可以使得窗口一直维持在Wmax附近,从而可以达到网络带宽的高利用率和协议本身的稳定性。

CUBIC窗口的增长函数:W(t) = C * (t-K)3 + Wmax, 其中C和β为常量。

t为当前时间距上一次窗口减小的时间差,而K就代表该函数从W增长到Wmax的时间周期。

CUBIC算法仿真曲线(来源CUBIC RFC)

通俗一点讲,假如我们知道了Wmax,那么CUBIC的核心思想就是需要在连续两次拥塞期间执行完上面的三次函数增长曲线,

6、基于精准带宽计算:BBR

BBR通过实时计算带宽和最小RTT来决定发送速率pacing rate和窗口大小cwnd。完全摒弃丢包作为拥塞控制的直接反馈因素。

TCP拥塞控制概述

 在不拥塞的前提下提高吞吐量

 

演变过程

Tahoe算法

只有两个状态,慢启动状态slow start(SS),拥塞避免状态congestion avoidance(CA)

一开始的阈值ssthresh默认为64k字节。

过程:

  • 开始慢启动过程从1mss开始指数增长,到拥塞的阈值ssthresh后进入拥塞避免状态线性增长。
  • 如果出现超时,拥塞的阀值ssthresh变成当前拥塞窗口cw的一半。同时超时重传超时的段。重新慢启动过程,强制拥塞窗口从1个mss开始指数增长,到拥塞的阀值ssthresh后进入拥塞避免状态线性增长。
  • 如果发生三个冗余ACK,拥塞的阈值ssthresh变成当前拥塞窗口cw的一半。同时快速重传三个冗余ACK的段。重新慢启动过程,强制拥塞窗口从1个mss开始指数增长,到拥塞的阀值ssthresh后进入拥塞避免状态线性增长。

        超时和发生三个冗余ACK的操作是基本一样的,区别是超时的话就超时重传超时的段,发生三个冗余ACK的话就快速重传三个冗余ACK的段

Tahoe算法的问题就是在发生三个冗余ACK时,强制拥塞窗口变成1个mss,代价比较大。因为没有发生超时,说明网络还有通讯能力;而发生三个冗余ACK,代表网络能正常接受丢失的mss的后三个。需要改进,在Tahoe算法基础上增加快速恢复的阶段,就有了Reno算法

Reno算法

三个状态,慢启动状态slow start(SS),拥塞避免状态congestion avoidance(CA),快恢复状态fast recovery(FR)

 无论是在慢启动状态(SS)还是拥塞避免状态(CA),只要发生三个冗余ACK,快速重传,cw减半(注意不是变成1了),阈值等于cw,进入快恢复状态,在快恢复状态下有三个情况:

  • 继续接到旧的冗余ACK,维持快恢复状态,快速重传,拥塞窗口cw加一,cw=cw+1MSS
  • 接收到新的ACK,冗余ACK数=0,进入拥塞避免状态(CA)线性增加而不是慢启动阶段,但是拥塞窗口cw等于阈值加三,cw=ssthresh+3,为什么是3,因为已经收到三个冗余ack,因此网络有能力。
  • 超时,和Tahoe处理一样。

Tahoe和Reno总结和区别

区别

New Reno算法

Reno的存在的问题,适合单个段丢失的情况。但是经常性拥塞时,快速重传完后可能会导致后续的段超时,从而进入ss阶段,使得cw降到1。

New Reno算法改进: 

New Reno存在的问题:效率低。一个RTT间隙里面发来一个部分确认PACK,那就发送一个丢失的段。

SACK算法

选择性确认,给定一些标记, 一个RTT可以重传丢失段

使用pipe和ScoreBoard,把什么时候发(pipe<cw)和发什么(先ScoreBoard,后新段)解耦

TCP是累计确认,没有tcp option的话,tcp头部长度为20B/4=5

SACK选择确认,在tcp option标出乱序被接受的段

因此通过这个方法,接收方可以表述乱序段被接受的情况

 发送方接到SACK后,在ScoreBoard计分板中存放需要重发的段的序列,在FR阶段重传(CW允许)

过程:

先重发计分板中丢失的段,再发新段

收到确认分为三种,是否为冗余ACK,是否在SACK选项中,是否为PACK新段得到确认,是否为RACK恢复ACK,组合成5种情况。

  

有两种情况:

CUBIC算法

遇到的问题:Reno在CA阶段,线性加1过于保守,不利于吞吐量的提升。(拥塞控制的目的是在在不拥塞的前提下提高吞吐量)

快速定位计算出窗口的最大值 

 

ECN算法

Explicit Congestion Notifacation,网络辅助信息拥塞控制

Tahoe和Reno都是靠事件来判断是否拥塞,比如定时器超时,收到三个冗余ACK。

上述两个算法都是通过端自身来统计和计算信息的。那么能否由网络反馈一些信息,那就需要修改TCP/IP协议。

IP数据报中两个标志位:

  • CE,Congestion Experienced,拥塞经历,给路由器使用。如果该路由器发生拥塞,经过该路由器的IP数据报CE位置1
  • ECT,ECN Capable Transport,ECN使能,使用ECN特性时需要将ECT位置1

TCP段中两个标志位:

  • CWR,Cogestion Window Reduce,源主机发现网络发生拥塞,源主机将拥塞窗口cw减半或者降低,那么就要将这个标志位置一
  • ECE,ECN-Echo,目标主机通过网络的反馈发现网络发生拥塞,目标主机将ECE置一,回传给源主机

 

过程:

在网络中经过拥塞的路由器:

 源主机得到ECE的反馈,降速

 

ECN存在的问题:

  1. 两个ECN使能的实体建立连接时,标志位不同,造成TCP三次握手时和其他实体不同
  2. 安全性问题,有攻击者在中间链路的路由器恶意修改ECN和CE位
  3. 只解决了拥塞时降速问题,没有解决不拥塞时增速问题

Vegas算法(基于延迟的拥塞控制 )

Reno类算法的问题:

  • 靠拥塞窗口的增加来探测,直到拥塞(SS状态指数增加,CA状态持续增加)
  • 发生拥塞时,反复降低拥塞窗口,导致速率波动,造成带宽利用率不高。因为这类算法利用拥塞是一种探测可用带宽的方式
  • 段的连续丢失,造成窗口反复降低,惩罚很重
  • 同时延迟比冗余ACK、超时来的更加敏感
  • Reno算法中的RTO,retransmit timeout,超时时间是基于500ms计时颗粒度计算的。先3个冗余ACK,后超时

事件发生顺序:冗余ACK事件 ->细颗粒度的超时事件 ->3个冗余ACK事件 ->细颗粒度的超时事件

过程:

BaseRTT是最小的RTT

Reno算法在慢启动状态下是一个RTT倍增cw,vegas是两个RTT倍增cw,温和一些

 

 重传的时机

vegas存在的问题,导致互联网使用的不多

  • 路径变化带来的RTT变化,误认为是拥塞,作出误操作
  • 如果网络中全部都是用vegas算法,那么整个网络会慢慢趋于平缓。但是与其他CUBIC、Reno算法协同工作时出现不公平性。vegas太敏感和太温和。主要用于可控的固定的场景,如机房间

BBR算法

BtlBW(Bottleneck link) and RTT based Congestion Control

  • Reno、CUBIC等算法,基于丢失的拥塞控制:吞吐震荡,延迟大,侵略性强
    • 有线低带宽时,丢失=拥塞。但是无线高带宽时,丢失=50%拥塞+50%出错。出现带宽震荡
    • 之前的网络交换节点buffer不大,现在的buffer大容量,造成延迟大。
  • BBR,基于模型的拥塞控制,不是基于丢失也不是基于延迟

模型概述:

  • 两个阶段:应用受限阶段和带宽受限阶段
  • 测量瓶颈链路带宽BtlBW和往返时延RTT。计算出BDP。反映网络路由和通信量的变化
  • 按照瓶颈链路带宽BtlBW控制主机的注入速率,按照BDP控制inflight数量

 模型会出现的三种状态

应用受限: 应用本身没有太多数据,pipe没充满

 带宽受限:pipe充满,瓶颈链路占满,有数据段在排队,但是buffer能承受这个队伍长度。出现拥塞。

 缓冲受限:pipe充满,buffer充满。出现丢包。

最核心问题:瓶颈链路带宽BtlBW和往返时延RTT不可同时测量。测量RTT时pipe需要处于轻载状态。但是测量BtlBW时pipe需要处于充满状态。谷歌B4网络采用现代鲁棒控制,让运行在不同的状态下,分别测准BtlBW和RTT。

测量RTT,在应用受限阶段

  • 握手时,刚刚开始建立连接,交互数据不多,处于应用受限阶段
  • RTT10秒没有更新
  • 高带宽时降低速率,10s抽出200ms。一个RTT发送4MSS,根据TCP option

测量BtlBW,在带宽受限阶段

 待确认段inflight<BDP

按照瓶颈链路带宽BtlBW控速,控制分组发送速率的间隔=包大小/发送速率=分组大小/(发送增益*瓶颈链路带宽),含义就是分组通过瓶颈链路耗费的时间

适应瓶颈链路带宽BtlBW变化

8个节拍,8个RTT时间,第一个节拍发1.25倍分组,第二个节拍发0.75倍分组,看RTT有没有增加,增加的话保持BtlBW不变,没有增加的话增加发送速率和BtlBW。之后六个节拍保持原有速度。

 BtlBW增加

BtlBW降低,需要等10RTT更新,因为BtlBW是取10个RTT中的最大值

具体算法

BBR状态机

绿色框代表处于稳定阶段

1、startup状态

2、Drain状态,排空

3、ProbeRTprop,探测RTT

  • 如果处于应用受限阶段,WR时间内没有更新,RTT不变
  • 如果处于高带宽状态,那就在10s里面抽200ms,一个RTT发送4MSS,强制变成应用受限阶段,测得RTT

代码:

分组确认:

发送分组:

                  

应用效果:

  • BBR的吞吐量是CUBIC的10倍以上
  • BBR抗丢包能力强,但是最多也就20%丢包率
  • CUBIC的延时是BBR的数倍
  • BBR受buffer影响不大,连接超时概率低

BBR存在的问题和解决方法:

资料参考:

  1. 《TCP/IP详解》卷1
  2. 中科大-郑烇教授,视频和教材
  3. 腾讯云社区文章,TCP拥塞控制及BBR原理分析 - 云+社区 - 腾讯云

以上是关于《TCP/IP详解》卷1第16章 TCP拥塞控制&&BBR分析的主要内容,如果未能解决你的问题,请参考以下文章

TCP/IP详解 卷1:协议 第18章TCP连接的建立与终止

《TCP/IP详解卷1:协议》第14章 DNS:域名系统---读书笔记

《TCP/IP详解卷1:协议》第12章 广播和多播---读书笔记

第2章 Internet地址结构 [TCP/IP详解 卷1:协议]

TCP/IP详解,卷1:协议--第8章 Traceroute程序

《TCP/IP 详解 卷1:协议》第 11 章:名称解析和域名系统