拥塞控制 vs 流量控制
在 TCP 中,拥塞窗口和接收窗口的最小值,是任意时刻内发送方确定能被发送出去的字节数。
拥塞窗口受拥塞控制的影响,接收窗口受流量控制的影响,以下会分别介绍拥塞控制和流量控制。
拥塞控制与流量控制本质上来说,是生产者消费者的模型,如下图所示:
拥塞控制
目的:通过减少发送方发送的数据量,起到阻止发送方到接收方之间的链路变得拥塞的目的。
实现:拥塞控制通过拥塞窗口实现,拥塞窗口由发送方维护,通过预估链路的拥塞程度实现。
好奇如我,如果看到上面的实现的定义,肯定会三连问,什么叫预估链路的拥塞程度?用什么标准判断链路是否拥塞?拥塞发生了怎么缓解拥塞?
别急,在思考上面的问题的时候,先思考个小问题,「你跟好朋友约饭,你怎么预估她来的路上是否堵车呢?」
答:很弱智的问题是不是,2019 年了,各种地图软件打开看看就能猜到了,那让我们在深入思考下,地图软件怎么评估哪个路段是否是堵车呢?
车辆有个天然的属性就是速度,取出历史和当前同一时刻数据,判断当前数据 - 历史数据的差值,若为整数,则下一时刻堵车的概率低;若为负数,则下一时刻堵车的概率高
让我们回到问题的主线上:
-
什么叫预估链路的拥塞程度?
基于历史数据判断未来链路发生拥塞的可能性称之为「预估链路的拥塞程度」
-
用什么标准判断链路是否拥塞?
- 基于丢包的:如 Reno、Cubic
- 基于时延的:如 Vegas、FastTCP (tcp 单边加速)
- 基于链路容量的:如 BBR
- 基于学习的:如 Remy
注:各种拥塞算法的实现,有兴趣请自行 google ,或者看下参考资料 (ps 主要是我自己也看的一头雾水,而照抄别人的感觉没啥意义
-
拥塞发生了怎么缓解拥塞?
送分题,减少发送的数据被,但是难点在于按照什么策略减少,是直接减少到 0 ,什么都不发了,还是按照某种策略减少发送的数据。
就好像没有一个东西能够满足所有场景一样,各种拥塞控制算法只是在侧重点上有所不同,并无好坏之分。不过有是否过时之分,毕竟互联网诞生之初,并没有这么高的带宽。
改进拥塞控制算法我目前理解就是两点:
- 如何快速的让拥塞窗口达到最大值
- 发什么拥塞的时候,如何尽可能少的减少拥塞窗口的值
本质上还是如何充分的利用带宽,不过还有一个 tcp 公平性的问题,在设计拥塞算法的时候需要考虑,先在脑子里留个概念吧,细节有空补补。
流量控制
目的:减少发送方发送的数据量,起到缓解接收方压力的目的。
实现:接收方控制发送方发送的数据大小,每次应答的时候通知发送方自己还剩余多少空间可以接受数据。
流量控制的实现是基于滑动窗口实现,具体细节如下:
- 接收方在 TCP 首部中的「窗口大小」字段写入自己可接受的缓存区大小,通过 ACK 包发送给发送方
- 「窗口大小」是发送方最多可发送的不需要 ACK 的字节数
问:接收方发现自己的缓存区满了要怎么处理?
答:将 TCP 首部的「窗口大小」设置为 0,此时发送方将不再发送数据,但需要定期发送一个窗口探测的数据包,是发送能够在窗口有空余的时候继续发送数据。(ps 不过这里为什么不是接收方主动通知呢?是因为不知道要发什么包嘛,还是主动推的话协议会复杂化,只是我也不知道……
写在最后,最近拖延症晚期,先写一点是一点吧……