learn-tech/专栏/全解网络协议/16我为什么与众不同-TCP高级篇(拥塞模型).md
2024-10-16 06:37:41 +08:00

12 KiB
Raw Blame History

                        因收到Google相关通知网站将会择期关闭。相关通知内容
                        
                        
                        16 我为什么与众不同 - TCP高级篇拥塞模型
                        首先我们可以肯定的是TCP协议是可靠的。这就是我们前面讲的TCP知识。它是可靠地从网络上的一个端点到另一端点获取数据但是它不希望使两者之间的网络不堪重负。TCP不想非常快的就开始发送数据这样会导致拥塞和数据包丢失。同样TCP也不想“欺负”其他的网络把其他所有协议都淘汰掉优先考虑自己的流量。因此通过TCP拥塞控制TCP能够确定网络上的拥塞并相应地调整其传输速率。

这可能与你想象的有一点不同。通常,我们开始传输该文件,并且我们想象的是,发送速度逐渐提高,并逐渐接近带宽。我们能够用吞吐量完全填满网络,并且该文件能够尽快通过链接传输。就像下图一样

但是理想很丰满现实很骨感。下图是在Wireshark的吞吐量图。

从图上可以看到吞吐量的变化。最初会上升然后略有下降。它会先恢复一段时间然后再次下降然后随着时间的推移缓慢重建。因此现实是TCP不会完全填充网络当我们将文件从一个端点传输到另一个端点时。会有很多事情来控制。造成这种情况的原因是TCP被设计为在端点之间具有不可预测的网络的情况下非常智能现实也确实如此。今天我们正在处理无线高延迟高损耗多路径高拥塞的情况。因此这两个端点需要确定它们之间网络中正在发生的事情并尽其最大可能地填充它并以最有效的方式将数据从A点移动到B点。而TCP正是通过拥塞机制来进行控制的。这也是为什么它很重要的原因。

拥塞窗口

让我们想象一下在客户端我们有一个大小限制为65535的TCP接收窗口。那么无论中间的网络大小如何发送方都只能一次将65535放到网络中传输。现在如果我们不传输大量数据或处于非常低的延迟环境中例如端点之间为1毫秒则接收窗口可能是足够的。但是如果我们试图通过高延迟的链接来传送大量数据窗口接收的数据量也不会减少。但是无论哪种方式发送者都受到接收窗口的限制。这是拥塞窗口起作用的地方。

让我们想象一下客户端的接收窗口现在大大增加到1GB。那么使用的是1GB的接收窗口。客户端很自信的堆服务器说“嘿服务器给我你所有的东西我能处理。你最多可以发送1GB的未确认数据。但是在这里发件人需要做出决定也就是思考一下。在引起拥塞问题之前它将在网络上发送多少是1GB吗还是512MB还是10Kb该服务器知道还有其他TCP连接和使用。它知道并非所有链接都相同。因此该服务器不知道中间是哪种网络。我们有穿越海洋的T1连接吗这两个端点之间是否有卫星连接还是说客户端只是一个交换机端口所以最开始的时候服务器不知道一次发送多少并且它不希望引起流量问题并引起争用和拥塞这将导致数据包丢失。因此该服务器可以传输的数据量是拥塞窗口或接收窗口的最小值。哪个值较小就使用哪个值。我们的这个例子接收器有很大很大的接收窗口。除非我们之间有一个非常非常牢固的网络否则我们不可能在拥塞窗口实现这一目标。这里变得有些意思了。TCP接收窗口的大小会在TCP的头中。还记得上一节讲的TCP Header中有一个Window Size吗

因此当工作站发送确认甚至数据包时它总是会告诉你必须使用多少窗口大小。在上面照片中可以看到实际的真实窗口大小值为262但由于我们使用的是窗口缩放所以实际上是一个更大的值。在这里我们可以看到对方可以一次发送33536。这个不是问题因为我们在接收缓冲区中可以拥有的数据量。我们永远不会在包头中看到它。实际上挖掘并找出实际值是什么几乎是不可能的。原因之一是因为这个数字一直在变。TCP总是增加拥塞窗口或减少拥塞窗口这取决于它从网络之间确定的结果。因此我们能做的最好的就是查看该拥塞窗口并确定这是吞吐量缓慢问题的根本原因吗

拥塞算法

我们知道了拥塞控制机制是什么让我们一起来看一些算法及其工作原理。TCP拥塞控制机制决定发送方如何使用网络上的带宽。还可以决定该设备遇到丢失或高延迟时将退后并恢复的速度。现在让我们来看一些拥塞控制算法的名字也许你以前听说过其中一些。比如vegasRenoNewRenoCUBIC等等。有很多不同的算法。随着时间的流逝和网络的变化我们发现它们已经经过调整和优化可以在不同类型的网络上更好地运行。例如当网络具有更高的带宽和更高的延迟跨过海洋下面的40GB连接通道我们开始意识到需要对TCP发送算法进行更改可能需要使它们更具“攻击性”而不必仅仅因为丢失一个数据包就减缓传输的速度。同样一些常见的拥塞控制算法取决于操作系统使用的TCP版本安装的补丁程序这些都会对使用哪种算法产生影响。我们来更深入地了解一下这些算法为何不同。

聊这些算法之前你自己先想一下都需要考虑什么第一个想到的核心组成部分是不是初始窗口大小这个是不是很重要小了会慢大了会丢失。初始窗口就是发送方在传输文件时立即发出的完整MSS(Maximum segment size数据包的大小。假设我们的服务器使用的是非常保守的拥塞控制机制它一次只发送两个全尺寸数据包。在发送更多数据之前它会等待这些数据包的确认返回返回后将可以继续发送更多内容。初始窗口大小的决定网络上发出了多少个数据包这些都取决于拥塞控制机制的使用。

比如在NewReno的某些实现中开始的窗口大小是四个MSS大小的数据包这是初始窗口设置。在许多CUBIC算法的实现中使用10个MSS作为初始窗口。初始窗口是拥塞算法的核心这表示的是最开始发送多少数据包。

拥塞机制的另一个核心组件是慢启动。什么意思呢就是我们的服务器它发送两个完整的MSS到客户端然后从客户端收到确认整个过程很顺畅。然后再测量一下在发送数据和接收确认之间的等待时间服务器会认为整个流程没有问题。之后服务器会将下次发送的MSS数量翻倍它将在下一次发送四个MSS然后等待这些确认返回。重复上面流程如果还是很顺畅会继续的将发出的数据包数量加倍。这是一种常见的机制你会在Reno和NewReno等一些较旧的算法中看到这种机制。

慢启动

我们来详细看一下慢启动的过程。

在我们的图表中我们可以看到时间是底部X轴表示往返时间Y轴表示发送包的数量。发送站通过发送两个完整的MSS来启动。它等待第一次网络往返的确认返回然后将拥塞窗口加倍接下来将为第二次往返发送四个MSS。如果这些都出去了那么认为没有任何问题那么我们将再次加倍第三次网络往返传输将获得8个MSS。如果所有这些都被成功接收并且我们收到了很好的回覆继续再次加倍。现在在某个时候根据算法以及该算法能够从网络中确定的延迟时间该算法将设置一个慢启动阈值图中的1这意味着你可以将网络上现有的MSS数量加倍直到碰到这一点。在这种情况下我们说该数量为16。在那之后我们从慢启动机制更改为避免拥塞机制。这就是说对于每个网络往返我们将只添加一个而不是将网络上的MSS数量加倍。因此对于第五次网络往返我们将有17个MSS也就是16 + 1。对于第6次网络往返我们将有18个MSS17 + 1这将缓慢增加拥塞窗口直到遇到丢包或拥塞为止图中的2。当我们遇到超时或发送数据包却没有收到响应时会发生什么这时候大多数拥塞控制算法所采用的是让步。在较早的日子里这个数字实际上会回到一半。将拥堵窗口缩小一半图3然后从慢启动重新开始直到再次达到慢启动阈值。但是随着时间的流逝网络连接的带宽不断提高在某些情况下延迟也有所增加这种倍增的后退策略有点激进了。就像我们在这里看到的那样仅由于遇到单个数据包丢失我们就损失一半的吞吐量。

因此,为了解决此问题,使用了另一个核心组件那就是-快速恢复。快速恢复可以帮助我们做的是,我们从拥挤窗口中的那个高点退回,但并不是一半的腰斩。而是退后一点然后再慢慢重建。

我们前面提到了使用哪种拥塞控制算法取决了很多事情初始窗口最初发出了多少个MSS是否使用慢启动机制还是快速启动慢启动阈值如何设置什么时候开始避免拥堵是否使用快速恢复还是如果遇到一些损失会重新回到慢速启动我们是否只会在看到数据包丢失的情况下才后退还是等待时间的变化会导致我们放慢速度所有这些都取决于你所使用的TCP算法并且它们都是不同的。让我们来看一些常见的拥塞算法及其独特之处。

NewReno是你可能听说过的一种在2000年代它非常流行许多不同的系统都在使用它。现在NewReno还在使用但是在长肥网络LFNlong fat network上它的性能很差比如海底隧道这种网络。如果你通过跨海洋的10GB连接发送文件但效果不佳则可能需要进行调查是否使用了NewReno。 CTCP - 这是Windows Server 2003和Windows 7上的默认拥塞控制机制。 CUBIC - 是在Windows 10和MacBooks上默认使用的。原因之一是因为它在长肥网络中效果非常好。它可以快速建立其拥塞窗口并且不会非常迅速地退后。如果看到丢失的数据包它不会退缩到一半。 Westwood - 你不是经常能看到这种机制,它是专为处理有损网络而设计的。 最后是BBR - 这是Google专门开发的它可以在大多数服务器中使用并且你还可以在Linux操作系统上进行实验。

拥塞检测机制

TCP如何知道出现问题并相应的退出其拥塞窗口决定拥塞算法退避的主要方法有两种

第一种是丢包。因此在这里我们可以看到服务器发送了两个数据包并且得到了很好的确认。然后发出四个数据包其中一个数据包丢失。这就是说我试过发出四个但是效果不好既然这样我就坚持每次网络往返都使用2MSS。 另一种拥塞检测机制是测量延时。服务器发送了几个数据包。就好像短跑比赛一样,这时候按下启动秒表。当看到这些数据包的确认返回时,便可以停止该秒表并测量延迟。该等待时间(延迟)不应该有显着变化。通常,仅当某处的链接出现拥塞时,它才会发生变化。让我们再想象一下,该服务器发送了几个数据包,但是这次要花费更多的时间才能从客户端取回确认。说明什么问题?是不是说明发生了拥堵。

拥塞机制可以算是TCP比较高级一点的知识希望你能对TCP的知识有了一个更深层次的理解。