Linux TCP 网络拥塞控制的困境

网络的多样性,导致各种各样的拥塞控制算法丛生,没有一种万能的拥塞控制算法可以适用于现有所有网络场景。

本文由腾讯WeTest授权发布,未经许可不得转载。

| 导语 TCP网络的核心是拥塞控制算法,而拥塞控制算法核心则是如何有效地检测网络拥塞,最大效率的利用网络带宽进行数据传输。网络的多样性,导致各种各样的拥塞控制算法丛生,然而越是研究,越是证明了一点:没有一种万能的拥塞控制算法可以适用于现有所有网络场景

1. TCP 拥塞退避策略

拥塞控制是一种分布式的用于实现多个竞争数据流共享网络资源的算法。其中拥塞则被定义为由于网络资源过载,从而导致网络用户侧观测到的概率性丢包以及时延的状态,而网络资源过载导致了网络的空间以及时间复用的效用降低。

现行的网络的复杂性是当时的网络设计者始料未及的。在TCP/IP协议数据流传输过程中,有统计显示TCP数据流占据了80%的网络流量,这就导致TCP数据遇到网络数据拥塞则是一个常态。 拥塞发生的主要原因是网络能够提供的资源不足以满足用户的需求,这些资源包括缓存空间、链路带宽容量和中间节点的处理能力。由于互联网的设计机制(任何人任何时间都能共享网络资源)导致其缺乏“接纳控制”能力,因此在网络资源不足时不能限制用户数量,只能靠降低服务质量来继续为用户服务, 也就是“尽力而为”服务。

TCP的拥塞退避由4个核心的算法组成:慢启动(slow start)、拥塞避免(Congestion voidance)、快速重传(Fast Retransmit)和快速恢复(Fast Recovery)。

1.1 慢启动(slow start)

该算法的思想主要是一种探测一下网路的拥塞程度,就是不要一开始就发送大量的数据,也就是说有小到大逐渐增加(指数)拥塞窗口的大小。

开始 cwnd=10
经过1个RTT后, cwnd=20 * 1=20
经过2个RTT后, cwnd=20 * 2=40
经过3个RTT后, cwnd=20 * 4=80
如果宽带为W,那么经过RTT * log2W时间就可以占满带宽。

1.2 拥塞避免(Congestion voidance)

如果按上述的慢启动的思想如果不加以控制的话,毫无疑问的发生网络拥塞,当cwnd很快增长上来的时候,也很快利用了网络的资源,但是cwnd不能一直这样增长,一定需要某个限制。TCP使用了一个慢启动门限(ssthresh)的变量,当cwnd超过该值后,慢启动结束,进入拥塞避免阶段。对于大多数的TCP是吸纳来说,ssthresh的值是65535(同样以16bit来计算)。 拥塞避免的思想就是转指数增大变为加法线性增大。这样就可以避免增长过快导致网路拥塞,慢慢的增加调整到网络的最佳值。具体ssthresh的用法如下:

  • 当cwnd<ssthresh时,使用慢开始算法。
  • 当cwnd>ssthresh时,改用拥塞避免算法。
  • 当cwnd=ssthresh时,慢开始与拥塞避免算法任意。

注意:如果当前的cwnd达到慢启动的阈值,则试探性的发送一个segment,如果服务器没有响应,TCP认为网络能力下降,必须降低慢启动阈值,同时为了避免形式继续恶化,有可能将窗口降低为1.

1.3 快速重传(Fast Retransmit)

RTO超时重传会导致TCP传输效率较低。目前Linux TCP实现是采用ACK或者SACK的机制来实现对数据包进行累积确认,预测数据包丢失,实现快速重传。快速重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置重传计时器时间到期。实际上,目前Linux的TCP快速重传算法,除了经典的三次ACK,还包括ER、FACK,以及最新的基于时间序的RACK的包丢失快速重传算法,做出了很多改良。

1.4 快速恢复(Fast Recovery)

其实快速恢复并不是单独存在的,它是快速重传的后续处理。通常认为客户端接收到3个ACK后,就会开始快速重传,但是如果还有更多的重复ACK呢,这个时候就是快速恢复要做的。

a、当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半(也即 cwnd=ssthresh/2).但是接下去并不执行慢开始算法;
b、考虑到此时能连续收到3个ACK,说明网络没有拥塞,执行加法原则,有几个ACK就加几个段的字节数,或者可以将cwnd=ssthresh,直接进入拥塞避免算法。

先给出教科书里面的一个图例:

然而Linux的实现的TCP快速恢复是经过google改良过的,实现了一种PRR的快速恢复算法,主要用于更快的快速恢复,更加贴合现今的网络。

2. TCP 网络中拥塞控制之困境

在现行网络当中,如何有效地检测网络拥塞,最大效率的利用网络带宽进行数据传输,则是拥塞控制算法的核心所在。但是随着现行网络的复杂度不断膨胀,静态的拥塞控制算法已然不适应于这个多变的网络,无法适用于所有的网络场景。这里例举两个场景:

  • bufferbloat问题:在last mile的核心路由里因为排队而导致缓存着大量的数据包,而导致网络传输的RTT异常变长,标准TCP协议的拥塞控制算法会在链路的瓶颈处将缓冲区填满,从而导致拥塞信号需要在很长的时间内才能反馈到发送端,导致发送端无法及时发现丢包。

  • 无线网络、移动网络中大量乱序以及链路丢包,而导致网络拥塞控制算法误认为是网络拥塞,导致发送端的保守行为,从而无法有效利用传输的带宽。

然而TCP网络中拥塞控制遇到的挑战远远不止上述的两个例子,下面给出现行TCP拥塞控制遇到的困境:

2.1 异质性

所谓的异质性,既是TCP的网络是由各种各样不同的子网络构成,而每个子网络包含不同的子拓扑,这就导致了不同的网络包含不同的链路特性。从带宽的角度来讲,链路质量可能是非常慢速如移动网络,或者是非常高速的链路如核心网络,数量级从kbps到G/s。从时延的角度来讲,场景的变化从本地网络通信到卫星通信,数量级从ms到s。这就导致了现实的网络场景(网络带宽以及端到端的时延组合)的多样性,这种多样性随着网络的快速发展,而变得越来越复杂。

然而在网络当中,无论是带宽亦或者时延都不是恒定不变的,而在网络当中可能由于不同层次的数据流竞争、动态路由等都会导致带宽和时延的变化。

在现今的网络当中,拥塞控制必须对这些多样化进行有效的处理。而Van Jacobson引入的拥塞控制原理更多的是基于一个静态的场景以及针对数量为几十个数据包的BDP(bandwidth-delay-product)的场景进行设计。随着网络的发展,这种拥塞控制算法已经越来越难以适应现今网络的BDP以及变化。在很多场景下,拥塞控制算法无法做出理想的反应,而导致资源利用率低。

目前基于Additive Increase Multiplicative Decrease (AIMD)理论的拥塞退避算法在现行的网络中过于保守,无法适用于现行的网络多样化的场景。在某些特定的场景可以调整拥塞控制参数来进行适配,然而这里存在一个根本性的挑战则是是否可以定义一个拥塞控制机制可以在一系列场景都可以表现良好,最大限度的适配于网络上的各种拥塞状态。

2.2 稳定性

对于在不同包大小、不同的网络时延RTT的真实网络环境里面,如果要使用控制理论对其建模是非常困难的。因此,一个简单的做法使用模拟环境对拥塞控制算法进行评估。显然,一个算法如果在一个简单的模拟环境下,都不能稳定,则表明这个算法是无法稳定的在真实的网络上进行使用的,然而模拟的环境简化了真实网络的很多可能性,算法在模拟环境稳定,但是面对复杂的现实网络环境依然存在很多不稳定的可能性。

TCP的稳定性的关键因素在于两个方面:

其一是在拥塞期间的AIMD的拥塞避免。这个因素是基于一个简单的、向量的分析实现的两个不同时延的控制端共享一个资源,这个因素是80年代的拥塞退避算法,沿用至今。

其二是包守恒定律。TCP发送方的拥塞控制操作是由ACK的接收来驱动或“控制”的。当TCP传输处于稳定阶段(cwnd取合适值),接收到ACK回复表明发送的数据包已被成功接收,因此可以继续发送操作,如马尔科夫链般,据此推理,稳定状态下的TCP拥塞行为,实际上是试图使在网络传输路径上的数据包守恒。这是基于“管道”模型(pipe model)的“数据包守恒”的原则(conservation of packets principle),即同一时刻在网络中传输的数据包数量是恒定的,只有当“旧”数据包离开网络后,才能发送“新”数据包进入网络。如果发送方收到一个ACK,则认为已经有一个数据包离开了网络,于是将拥塞窗口加1。如果“数据包守恒”原则能够得到严格遵守,那么网络中将很少会发生拥塞;本质上,拥塞控制的目的就是找到违反该原则的地方并进行修正。然后很多所谓的优化过于激进导致并不符合包守恒定律,给网络拥塞添堵。

2.3 公平性

目前网络拥塞控制算法有很多种,如何使得拥塞控制算法在所有的网络当中取得相应的公平性呢?这是一个值得思考的问题,也是拥塞算法推广前需要进行评估的一个问题。例如两个相同的数据流竞争一条带宽限制的信道,应该是公平的进行共享,而不是存在差异。如果一个拥塞控制算法无法保证数据流的公平性,最终则会导致网络流量的侵略性以及造成得此失彼的结果。

2.4 网络支持拥塞控制

如果说要求中间网络设备支持拥塞控制,发送端或者接收端可以根据显式的网络反馈进行调整拥塞控制算法,这样连接的端点能够更好的掌握当前这条链路的上的网络特征,能够更加精确的根据网络拥塞情况进行拥塞控制决策。

然而这个更多的是硬件厂商需要关注的事情。需要网络支持拥塞控制存在很多难点,网络如何进行信息采集、如何保存网络的状态、反馈信号以什么频率返回,性能和鲁棒性等等,如果要硬件支持,推广是个问题,还有就是很多家庭路由不会考虑到支持拥塞控制。

2.5 Corruption Loss

常见的拥塞控制算法reno、cubic都是基于包丢失检测算法的基础上实现进行的拥塞控制的。诚然,路由器的队列溢出,可能会导致适当的包丢失。但是还有其他可能原因导致包丢失,现在越来越多的无线网络,可能会因为Corruption Loss导致包丢失,这种场景下使用典型的基于包丢失的拥塞控制机制则不是很合适。tcp协议栈在无线以及卫星通信的议题的优化已经被关注了。如果要解决Corruption Loss在设计拥塞控制算法,必须考虑一下两个问题的解决:

  • How is corruption detected?
  • What should be the reaction?

这里实质上是对如何检测Corruption以及如何应对Corruption。在TCP Westwood,它会根据三个DupACKs或者是RTO超时,对拥塞控制窗口进行调整,调整成测量得到的带宽。这个带宽的测量则是采用ACK计数频率。这种设置可以在噪声信号提供一个有效的吞吐量,而不是盲目的将窗口减少半(标准tcp的做法)。

2.6 性能公式

基于包丢失的TCP拥塞控制算法是基于包数量的计数的,而不会理会包的大小。关于TCP的拥塞避免算法的性能,最有名的是平方根公式(square root formula),这里将这个平方根公式进行简化来表示TCP的吞吐量。TCP吞吐量B的大小与RTT成正比,而与数据包丢失的概率平方根成反比:

B ~ C*S/(RTT*sqrt(p))

    where
         C     is a constant
         S     is the TCP segment size (in bytes)
         RTT   is the end-to-end round-trip time of the TCP
               connection (in seconds)
         p     is the packet drop probability

然而这个是理论推算出来的公式,实际上现行网络上还要复杂得多,更何况很多时候RTT、包丢失都是无法完全精确测量的。

2.7 慢启动

当一个新的连接,TCP是无法获知这条链路的带宽以及RTT时间的,TCP连接采用的是慢启动实施流的发送,这就导致TCP连接会在较长的时间内才能找到最佳的BDP,另外慢启动的指数递增,在一个很大的拥塞控制窗口可能会导致大量的数据包丢失(慢启动数据包过冲)。最后,慢启动无法保证多个数据流的竞争带宽的收敛行为,考虑一个long-lived的数据流和一个慢启动的数据流,很明显的long-lived的数据流更具有侵略性,会占用更多的信道资源。 基于带宽估计的技术可以解决这个问题,采用时延或者速率步进的拥塞控制算法,可以更加公平的实施数据流共享。

2.8 网络数据流的弹性

不同弹性数据应用对流量都会有不同的诉求:短期弹性业务,如http以及即时消息流量,或者说是长文件传输的长期业务。一个好的拥塞控制方案,应该能够区分不同的流量诉求,对不同优先级别的数据流分配不同的流量带宽配额。协调流量类优先级和拥塞控制之间关系,一种做法是使用拥塞信号(损失或者显性通知),另外一种是使用AQM机制实现,在一个独立队列里面,较高优先级的流量给出更高的调度优先级和更低的拥塞级别。

2.9 网络流量的侵略

网络是一个自治系统,当前的互联网架构中,拥塞控制取决于各自的利益行事。目前越来越多的互联网流量来自于应用程序设计不使用拥塞控制方案如使用UDP方案,这就会导致互联网的拥塞崩溃。例如目前基于互联网视频点播的服务,需要传输更加大的数据速率,而不使用拥塞控制正变得普及。对于带宽的诉求,而导致的网络不使用拥塞控制,但是同时可能会导致被利用用于流量攻击。

2.10 RTT 测量

RTT的估算是TCP连接一个非常重要的参数。无论是RTO超时重传,还是其他的TCP定时器机制都是依赖于RTT这个值进行调整。RTT的测量技术包括两种技术:

  • 主动测试:使用一个特别的探测数据包到网络,测量其反馈的时间。例如使用ICMP。
  • 被动测试:是用客户端的ACK,使用滤波器对RTT进行平滑,估算。目前Linux内核采用的是被动测试。

目前RTT测量遇到的问题包括:

  • 最佳的RTT测量频率
  • RTT过滤器设计
  • 反馈信号失败的RTT默认值
  • 时钟粒度:RTT估计取决于时钟协议栈的粒度。

2.11 多路径的网络拥塞控制

TCP的网络路径是多变,如何有效的利用多条路径的链路实施带宽的最大利用,都是有益的。

3. 参考资料

  1. Open Research Issues in Internet Congestion Control
  2. 网络基本功:TCP拥塞控制机制

 

关于腾讯WeTest (wetest.qq.com)

 

腾讯WeTest是腾讯游戏官方推出的一站式游戏测试平台,用十年腾讯游戏测试经验帮助广大开发者对游戏开发全生命周期进行质量保障。腾讯WeTest提供:适配兼容测试;云端真机调试;安全测试;耗电量测试;服务器性能测试;舆情监控等服务。

最新文章
1客户案例研究:专家安全扫描,守护金融银行小程序安全和私密性 WeTest私有化部署的定制扫描平台让金融银行客户能无成本接入扫描系统并迅速上手使用。客户能方便快捷地根据定制手册进行自助扫描,根据生成的扫描报告,详细洞察漏洞,快速识别并准确定位问题根源。
2客户案例研究:专家渗透测试,洞察电子商务小程序重大交易漏洞 通过WeTest渗透测试服务,某知名零售公司旗下的在线购物类小程序中发现了8处安全风险,我们的安全专家为客户提供了详细的漏洞报告,提供了较为清晰完整的安全加固方案。在回归测试中,中危以上风险均被解决。
3自查小程序4大安全隐患!文末免费赠送小程序安全扫描专业版! 腾讯WeTest现面向小程序开发者开放免费申请使用小程序安全扫描专业版,助您提前发现全面的安全漏洞。扫描文中问卷二维码或点击问卷链接,即可报名参与免费领取活动。
4浅谈渗透测试服务在泛互行业带来的价值 在泛互联网行业中,渗透测试服务对于保障企业的网络安全至关重要。
5云手机卡顿/无特定设备/商店登录受限怎么办?WeTest专有云帮您解决! 公有云满足了大量小微企业、个人的测试需求;随着客户深入使用,也遇到了一系列新问题。本篇将对几个常见问题予以解答
购买
客服
反馈