面试考点 | 深入理解 TCP 拥塞控制
随着网络技术的飞速发展,越来越多的工作依赖网络完成,基于互联网的实时通信系统的质量和实时性也很大程度也依赖于网络质量。然而,在Internet的TCP/IP体系结构中,拥塞的发生是其固有的属性。
网络拥塞是指用户对网络资源(包括链路带宽、存储空间和处理器处理能力等)的需求超过了固有的处理能力和容量, 相比UDP,TCP自身具有拥塞控制机制,并且需要保障数据可靠传输,这会对基于TCP的音视频实时传输造成一定的困扰。
本文将深入讲解TCP的拥塞控制机制以及如何基于TCP传输来设计一个实时音视频系统。
PART 01
TCP拥塞控制简介
从广义上讲,TCP拥塞控制的是让每个源确定网络中有多少可用容量,以便它知道可以安全传输多少数据包,防止过多的数据注入到网络中,使网络中的路由或者链路不至于过载。
在网络中发生拥塞时,拥塞控制减少向网络中发送数据的速度,防止造成恶性循环;同时在网络空闲时,提高发送数据的速度,最大限度地利用网络资源。
当然,确定可用网络容量并非易事,不断有新的TCP连接的加入和减少;更糟糕的是,可用带宽会随着时间的推移而变化,这意味着任何给定的源都必须能够调整它在传输中的数据包数量。
PART 02
理论上,拥塞控制有两种实现方式:
端到端拥塞控制:在这种拥塞控制方法中,由发送端自己来判断是否拥塞,然后调整传输速率;
网络辅助的拥塞控制:由网络中的路由器来告诉发送方,网络的拥塞情况。
通过网络层反馈拥塞信息实现拥塞控制的方法,需要得到网络设备的支持,改造底层硬件;现在常用的TCP协议大都采用的是端到端拥塞控制,即由发送端自己来判断是否拥塞;若发送端检测到这种现象,就应该降低发送数据的速率,若没有,则可以慢慢提高速率。拥塞控制算法需要解决以下三个问题:
TCP如何限制数据的发送速率;
TCP如何检测网络中是否拥塞;
TCP采用什么算法来调整速率(什么时候调整,调整多少)。
TCP拥塞控制算法发展的过程当中出现了以下几种不一样的思路:
基于丢包的拥塞控制:将丢包视为出现拥塞,采取缓慢探测的方式,逐渐增大拥塞窗口,当出现丢包时,将拥塞窗口减少,如Tahoe、Reno、BIC-TCP、Cubic等;
基于时延的拥塞控制:将时延增长视为出现拥塞,延时增长时增大拥塞窗口,延时减少时减少拥塞窗口,如Vegas、Westwood等;
基于链路容量的拥塞控制:实时测量网络带宽和时延,认为网络上报文总量大于带宽时延乘积时出现了拥塞,如BBR;
基于学习的拥塞控制:没有特定的拥塞信号,而是借助评价函数,基于训练数据,使用机器学习的方法造成一个控制策略,如Remy。
PART 03
Reno算法所包含的慢启动、拥塞避免和快速重传、快速恢复机制,是现有的众多基于丢包的拥塞控制算法的基础。发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量和慢开始门限ssthresh状态变量。ssthresh的用法如下:
当cwnd
当cwnd>ssthresh时,改用拥塞避免算法。
当cwnd=ssthresh时,慢开始与拥塞避免算法任意。
(1)慢热启动算法 – Slow Start
连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据。
每当收到一个ACK,cwnd++; 呈线性上升。
每当过了一个RTT,cwnd = cwnd*2; 呈指数上升。
(2)拥塞避免算法 – Congestion Avoidance
当cwnd >= ssthresh时,就会进入“拥塞避免算法”。算法如下:
收到一个ACK时,cwnd = cwnd + 1/cwnd
当每过一个RTT时,cwnd = cwnd + 1
(3)拥塞状态算法 – Fast Retransmit
Reno在收到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 ,然后进入拥塞避免算法。
BIC-TCP 和 CUBIC
TCP-Reno在大拥塞窗口环境下,由于一个数据包的丢失所带来的窗口缩小要花费很长的时间来恢复(每次仅增加1),这样,带宽利用率不可能很高且随着网络的链路带宽不断提升,这种弊端将越来越明显。
为了改善Reno拥塞避免阶段的表现,BIC-TCP提出这样一个二分思想的:当出现丢包的时候,说明最佳窗口值应该比这个值小,那么BIC就把此时的cwnd设置为max_win,把乘法减小后的值设置为min_win,然后BIC就开始在这两者之间执行二分思想--每次跳到max_win和min_win的中点。
BIC-TCP在高速网络中具有良好的可扩展性、自身竞争流之间的公平性和低窗口振荡的稳定性。然而,BIC-TCP的拥塞控制窗口增长仍然可能会过大,特别是在短RTT或低速网络下。此外,在拥塞窗口控制的几个不同阶段(二进制搜索增加、最大探测、Smax和Smin)增加了协议实现和性能分析的复杂性。
CUBIC是BIC-TCP的改进算法,CUBIC算法通过寻找一个新的窗口增长函数,三次方函数,在保持BIC-TCP的优势的同时(特别是它的稳定性和可伸缩性),同时简化了窗口控制的复杂度。CUBIC窗口控制函数如下:
其中,W(t)是在时间t时,窗口的大小,C为CUBIC参数,t为上次减窗经过的时间,K为上述函数在没有进一步损失事件时将W增加到Wmax所需要的时间周期,当发生拥塞事件时,CUBIC将当前cwnd设置为Wmax * β,乘法减小系数;由此可知K是:
当cwnd < Wmax. CUBIC在凸函数区域,即拥塞避免区间,cwnd的增长随时间的增加而变小; 当cwnd>=Wmax. CUBIC在凹函数区域,即新的Wmax 探测区域,当距离上次发生拥塞事件越久,cwnd 增长越快。
TCPW (TCP Westwood)
不同于基于丢包的拥塞控制,TCPW发送端监控ACK报文的接收速率,进而估算当前连接可达到的数据发送速率(可用带宽)。
当发送端检测到丢包时(超时或者3个重复ACK),发送端根据估算的发送速率设置拥塞窗口大小(cwnd)和慢启动阈值(ssthresh)。
为了方便理解,假设 tk – tk-1 是一个常量;当前的带宽评估可以可以简化为:
因为最优带宽和延迟无法同时测量(btlBw的测量会造成存在网络缓存增加RTT,而RTprop的测量要求网络缓存为空),所以分别估计带宽(btlBw)和延迟(RTprop),最后计算出cwnd。同时增加变量pacing rate(btlBw * 增益系数),用于控制发送端的发送速率,以解决发送端突发造成的网络排队问题。
TCP BBR一方面能够提升丢包环境下的发送速率,充分利用网络带宽,同时,也能够降低网络链路buffer的使用率,从而降低传输延时。TCP BBR 不仅适合TCP场景,同时QUIC也使用了BBR作为拥塞控制算法。
PART 04
虽然现在的实时多媒体通讯大部分都是基于UDP协议来实现,但是也存在一些情况,需要通过TCP来传输音视频;例如UDP端口屏蔽。相对于UDP数据传输的丢包,乱序, TCP网络下的传输数据延时大,队头阻塞等问题,为实时音视频传输也带来了更大的挑战。
实时多媒体的一些特点:
对于视频高清的需求,大码率场景下,单位吞吐大幅增加,单帧大小大幅增加,导致网络丢包数大幅增加,
实时通信对低延迟的要求,导致对数据传输的实时性的要求高。
为了更好的提升实时多媒体QoS,在TCP 环境下,设置拥塞控制和流量控制,需要考虑到以下一些的方面:
快速地检测到网络的拥塞事件发生;
精准的控制编码码率,特别是对视频关键帧的编码,避免出现大的网络冲击;
更积极的网络探测,对网络带宽的充分利用,可以带来更好的音视频体验;
通过simulcast和SVC, 在带宽不足的情况下,尽量保证音视频的实时性和流畅度;
尽量避免发送无效数据冲击网络,例如FEC、NACK。
PART 05
总结
拥塞控制应该是TCP中相对比较复杂的一个部分了,通过介绍TCP拥塞控制设计思想以及一些常用拥塞控制算法的设计思路,希望大家能对TCP拥塞控制有更好的了解。
技术交流,欢迎加我微信:ezglumes ,拉你入技术交流群。
私信领取相关资料
推荐阅读:
觉得不错,点个在看呗~