谷歌在网络研究、变革以及将这些变革推广到整个互联网方面有着悠久的历史。2011年,他们发表了一篇我最喜欢的论文,描述了他们决定将整个基础设施上的TCP初始拥塞窗口从1增加到10。不久之后,他们向IETF提交了一份RFC,最终这成为了互联网标准。
我认为现在是时候重新审视那篇论文,并更新谷歌对现代互联网的建议了。
本文的英文原版:An Argument for Increasing TCP's Initial Congestion Window ... Again
TCP使用一种称为滑动窗口的概念来管理网络中任何给定时间内传输的数据量。接收方管理一个接收窗口,告诉发送方它一次愿意接收多少数据。在现代TCP中,接收窗口被设置得很高,只有在接收方容量不足时才会减少。其目标是确保接收方不会因窗口过小而限制数据传输速度。
与此同时,发送方管理一个称为拥塞窗口的值。这个值是发送方在需要暂停并等待接收方响应之前可以一次性发送的数据包数量。存在各种拥塞控制算法来调整拥塞窗口,但它们的共同目标是在不受到网络中某处拥塞或数据包丢失的影响下,尽可能快速地提升传输速度。
这些拥塞控制算法需要一个起始值,称为初始拥塞窗口。这个值决定了连接开始时可以发送的数据量。
在传统TCP(2010年之前),该值根据操作系统和软件的不同,设置在1到3之间。当时主要的拥塞控制算法TCP New Reno会在每个往返行程中,如果没有数据包丢失,就将拥塞窗口增加初始拥塞窗口的大小。因此,一个没有丢失的数据包的成功连接看起来大致如下:
初始拥塞窗口:2。发送2个数据包(3 KB)。 拥塞窗口:4。发送6 KB。 拥塞窗口:6。发送9 KB。 如此类推……
如果该连接遇到一些数据包丢失,那么拥塞窗口就会减半,并且必须缓慢恢复。最终,在一个长连接中,拥塞窗口会稳定在一个相对狭窄的值范围内,这种稳定状态被称为收敛。
对于TCP设计的网络流量而言,这种方案是合理的。大文件传输几乎不受这种初始加速期的影响。根据连接的往返时间,收敛可能在1到2秒内发生,这对于预计需要花费数分钟的文件传输来说并不算太久。
然而,这种收敛期对互联网上主要的通信方式产生了不利影响:网页加载和API调用。
网页加载和API调用都使用HTTP(s),而在2000年代末,它们总是使用TCP作为传输层。
典型的HTTP请求在网络上的表现如下:
建立TCP连接 建立TLS加密 客户端发送HTTP请求(从20到8000字节不等) 服务器发送HTTP响应(从100字节到10 MB不等) 至关重要的是,请求和响应大小的统计分布都偏向于这些范围的高端。我当然不是第一个说互联网臃肿的人。
当TCP的初始拥塞窗口设置为像2这样的值时,单个往返行程中可以发送的最大请求或响应是3 KB。而在2011年,这仅占互联网上大约40%的响应。这意味着60%需要加载以渲染网页的资源必须至少等待一个额外的往返行程才能完全下载。对于典型的互联网往返行程来说,这意味着每个可能超过3 KB的60多个资产都要额外增加30毫秒。这意味着这个网页将额外花费1.2秒来加载。
鉴于这些数据,谷歌选择将其基础设施上的初始拥塞窗口增加到10,一个往返行程的数据截止值为15 KB。他们的计算表明,这将允许近85%提供给用户的服务资产在单个往返行程中加载。
然而,在2020年代的互联网上,这并不成立。JavaScript和图像的使用急剧增加,因此现代网站上的初始页面加载由数百个资产组成,其中大多数资产的大小为数百KB。现代互联网的臃肿增加使我们再次遇到了同样的问题。
我们现在面临的挑战是,仅仅将初始拥塞窗口再增加一个数量级可能是适得其反的。如果互联网上的所有网络服务器都开始一次性发送数百个数据包,我们只会造成TCP试图避免的拥塞和数据包丢失。几乎在任何地方,存储都是便宜的,但带宽是昂贵的。正因为如此,许多网络设备都连接到带宽较低的链路上,并且拥有大量存储。这意味着这些设备拥有深度缓冲区。一个试图从低带宽链路中退出的数据包可能会在缓冲区中等待很长时间,然后才能重新回到网络中。
想象一下一个家庭网络设置,互联网上传速度为10 Mbps,但路由器与某人的计算机之间的连接速度为1 Gbps。如果计算机试图以1 Gbps的速度发送东西,这些数据包就会在路由器上积压,而它们从另一端以10 Mbps的速度出来。
这个问题被称为缓冲区膨胀,它是存在缓慢增加拥塞窗口的主要原因之一。
幸运的是,谷歌的另一项发明来拯救我们。谷歌开发了一种名为BBR的拥塞控制算法,它与其他正在使用的算法完全不同。大多数算法将数据包丢失视为减少拥塞窗口的信号。在开发BBR时,谷歌假设数据包丢失是短暂的。现在存在数据包丢失并不能准确预测20毫秒后是否会发生数据包丢失。然而,由于缓冲区膨胀导致的拥塞则更具可预测性。
因此,BBR主要忽略数据包丢失,而是密切监视拥塞迹象。当数据包在某个网络设备的缓冲区中卡住时,它们到达目的地的时间会更长。这意味着对这些数据包的响应也会被延迟。BBR查看连接中的往返时间变化,并利用这一点来识别拥塞。如果存在拥塞,那么拥塞窗口就会减少。
因此,为了使TCP在现代互联网上具有高性能,我们需要做几件事:
将初始拥塞窗口增加到一个更高的合理数字(我觉得这个数字应该在20到40之间) 将BBR作为网络服务器和API服务器的默认拥塞控制算法。
我承认我的帖子中存在一些不一致。为什么是我而不是谷歌来做这件事呢?
答案很简单:谷歌已经很大程度上从TCP转向了其他技术。谷歌还开发了QUIC,即基于UDP的HTTP。不再有拥塞窗口需要处理,因此可以一次性发送整个消息。而且大多数时候,如果有任何数据包丢失,重新传输整个消息比等待TCP以合适的速度开始传输要快。
然而,我认为QUIC并不意味着我们可以忽略TCP的调整。首先,企业大多禁用了QUIC,并迫使像谷歌这样的网站降级回TCP。这是因为只有一个防火墙供应商能够解密并检查QUIC流量(Go Fortinet!)。其他每个供应商都提供了一个设置,可以在整个网络上禁用QUIC支持。其次,总是存在不支持现代协议的遗留设备。通过更好地调整TCP,我们也可以为这些遗留设备提供更好的互联网体验。
只要我们能够谨慎行事,并借助TCP BBR作为拥塞控制协议,互联网就准备好再次增加TCP的初始拥塞窗口了。
我将继续调查和讨论现代互联网上最具性能的TCP设置,并希望我能推动一些采用,使现代网络对每个人来说都更快。