Facebook的大部分流量现在使用Quic和HTTP/3

2020-10-22 08:51:38

我们正在用Quic取代互联网几十年来使用的事实上的协议,这是我们为优化我们的网络协议,为人们创造更好的使用我们服务的体验而采取的最新和最激进的步骤。今天,超过75%的互联网流量使用Quic和HTTP/3(我们将Quic和HTTP/3统称为Quic)。Quic已经在几个指标上显示出显著的改进,包括请求错误、尾部延迟、响应头大小,以及许多其他有意义地影响使用我们应用程序的用户体验的指标。

互联网工程任务组(IETF)目前正在开发用于标准化的QUIC和HTTP/3。

广义地说,QUIC是传输控制协议(TCP)的替代协议,TCP是互联网通信的主要协议之一。Quic最初由谷歌内部开发,名为Google Quic,或gQUIC,并于2015年提交给IETF。从那时起,更广泛的IETF社区对其进行了重新设计和改进,形成了我们现在称为Quic的新协议。HTTP/3是HTTP的下一代,HTTP是基于Web的应用程序和服务器的标准协议。总之,Quic和HTTP/3代表了以互联网为中心的最新和最伟大的协议,融合了我们、谷歌和IETF社区通过在互联网上运行协议而学到的数十年的最佳实践和经验教训。

QUIC和HTTP/3通常优于TCP和HTTP/2,而TCP和HTTP/2又优于TCP和HTTP/1.1。TCP和HTTP/2首先引入了允许单个网络连接在称为流复用的过程中支持多个数据流的概念。Quic和HTTP/3更进一步,通过避免TCP可怕的队头阻塞(丢失的数据包会堵塞连接上的所有流并减慢连接上的所有流),从而允许流真正独立。

Quic采用最先进的丢失恢复技术,这使得它在恶劣的网络条件下比大多数TCP实现执行得更好。TCP也容易僵化,协议很难升级,因为网络中间盒(如防火墙)会对数据包的格式进行假设。QUIC通过完全加密避免了这个问题,使协议的可扩展性成为一等公民,并保证将来可以进行改进。Quic还允许以新的方式通过QLOG检测、观察和可视化传输行为,QLOG是一种专门为Quic设计的基于JSON的跟踪格式。

我们开发了我们自己的Quic实现,称为mvfst,以便在我们自己的系统上快速测试和部署Quic。我们有编写和部署自己的协议实现的历史,首先是使用HTTP客户端/服务器库Proxygen,然后是Zero协议,然后是Fizz,即我们的TLS1.3实现。Facebook应用程序利用Fizz和Proxygen通过Proxygen Mobile与我们的服务器进行通信。我们还为TLS开发了两个安全解决方案,一个称为委托凭据的扩展,用于保护证书和TLS上的DNS,用于加密和验证TLS上的Web流量。

我们希望我们的新协议能够与我们现有的软件无缝集成,并允许我们的开发人员快速工作。作为试验场,我们决定在Facebook网络流量的一个大子集上部署Quic,特别是内部网络流量,其中包括到Facebook的代理公共流量。如果Quic不能很好地处理内部流量,我们知道它在更大的互联网上也可能不能很好地工作。

除了消除Bug和其他有问题的行为之外,此策略还让我们设计了一种方法,使我们的网络负载均衡器深入了解Quic,并维护我们的负载均衡器的零停机释放保证。

有了这个坚实的基础,我们开始向互联网上的人们部署Quic。由于mvfst的设计,我们能够顺利地将Quic Support集成到Proxygen Mobile中。

Facebook应用程序是我们在互联网上使用Quic的第一个目标。Facebook有一个成熟的基础设施,允许我们在将应用程序的更改发布给数十亿人之前,以有限的方式安全地推出这些更改。我们从一个实验开始,在这个实验中,我们在Facebook应用程序中为动态GraphQL请求启用了Quic。这些请求在响应中没有静态内容,例如图像和视频。

我们的测试表明,Quic在几个指标上都有改进。与HTTP/2相比,Facebook上的用户体验到请求错误减少了6%,尾部延迟减少了20%,响应头大小减少了5%。这也对其他指标产生了级联效应,表明Quic极大地增强了人们的体验。

然而,也有一些倒退。最令人费解的是,尽管Quic只针对动态请求启用,但我们观察到使用TCP下载的静态内容的错误率增加了。其根本原因是我们在将流量转换到Quic时遇到的一个共同主题:应用程序逻辑基于对其他类型内容的请求的速度和可靠性来更改对某些类型内容的请求类型和数量。因此,改进一种类型的请求可能会对其他类型的请求产生有害的副作用。

例如,调整应用程序向服务器请求新静态内容的积极程度的启发式方法会导致Quic出现问题。例如,当应用程序请求加载News Feed的文本内容时,它会等待查看该请求需要多长时间,然后确定从那里发出多少图像/视频请求。我们发现启发式可以使用任意阈值进行调整,这对于TCP来说可能工作得很好。但当我们切换到Quic时,这些阈值并不准确,应用程序试图一次请求太多,最终导致News Feed需要更长的时间才能加载。

下一步是为Facebook应用程序中的静态内容(如图像和视频)部署Quic。然而,在这样做之前,我们必须解决两个主要问题:mvfst的CPU效率和我们的主要拥塞控制实现BBR的有效性。

到目前为止,mvfst的设计初衷是帮助开发人员快速行动,跟上Quic不断变化的草案。与静态请求相比,动态请求的响应相对较小,因此不需要大量的CPU使用量,也不会让拥塞控制器进行测试。

为了解决这些问题,我们开发了性能测试工具,使我们能够评估CPU使用率以及拥塞控制器利用网络资源的效率。我们在负载均衡器中使用这些工具和Quic的合成负载测试进行了一些改进。例如,一个重要的领域是优化我们如何调整UDP数据包的速度,以实现更顺畅的数据传输。为了提高CPU使用率,我们采用了许多技术,包括使用通用分段卸载(GSO)来一次高效地发送成批的UDP数据包。我们还优化了处理未确认的QUIC数据的数据结构和算法。

在为Facebook应用程序中的所有内容打开Quic之前,我们与几个利益相关者合作,包括我们的视频工程师。他们对重要的产品指标有深刻的理解,并在我们启用Quic时帮助我们分析Facebook应用程序中的实验结果。

实验表明,Quic对Facebook应用程序中的视频指标产生了革命性的影响。平均重新缓冲间隔时间(MTBR)是对缓冲事件之间时间的度量,根据平台的不同,总体上可提高高达22%。视频请求的总错误计数减少了8%。视频摊位率下降20%。其他几个指标,包括考虑了各种因素和特别是异常值条件的指标,也得到了显著改进。Quic改善了视频观看体验,对条件相对较差的网络产生了过大的影响,特别是新兴市场的网络。

但通往这些结果的道路上也有自己的路障。与我们处理动态内容的经历类似,我们在应用程序中遇到了针对TCP行为进行调整的启发式方法。例如,iOS和Android上的应用程序有不同的机制来估计可用下载带宽。在使用Quic时,这些估计器有时会高估可用带宽,导致应用程序播放超出网络支持的更高质量的视频,并导致停机。

我们还必须调整和迭代流控制参数。流量控制限制了接收方愿意从发送方缓冲的数据量。Facebook应用程序对HTTP/2有一个静态定义的流量控制限制,该限制是针对TCP隐式调优的,在使用Quic时表现不佳。为了找到新的最优流量控制值,我们进行了一些实验迭代。

Quic在Facebook应用程序上的表现证明了它有能力改善人们在互联网上的体验,即使是在Facebook这样丰富而复杂的应用程序上也是如此。未来,我们计划继续利用Quic的更多现有功能,如连接迁移和真正的0-RTT连接建立,并投资于改进拥塞控制和损失恢复。

我们也在Instagram应用程序上部署了Quic,使用与我们的Facebook部署相同的策略-在Instagram的一小部分流量上进行测试,然后扩大规模。今天,Quic被部署在用于iOS的Instagram和用于Android的Instagram上。两个版本的Instagram都看到了与Facebook应用程序相当或更好的指标。Facebook和Instagram在网络上也启用了Quic,所以随着更多的网络浏览器支持Quic,就像谷歌最近对Chrome和苹果对Safari测试版所做的那样,更多的人将从这些改进中受益。除了Instagram,我们相信我们可以将Quic的好处带到我们应用系列的每一种体验中,Quic最终不仅代表了Facebook的大部分互联网流量,而且代表了整个Facebook的互联网流量。

IETF有望在2021年的某个时候将QUIC协议最终确定为征求意见(RFC)文档。一旦发生这种情况,甚至会有更多的网站、应用程序和网络库开始提供Quic供一般用户使用。在不久的将来,像Quic这样的新协议将对解锁创新的互联网应用至关重要。对我们来说,Quic是一个起点,我们可以从这个起点继续提升人们的Facebook体验。

Facebook内外有如此多的人使这一部署成为可能。我们要感谢过去几年来参加IETF Quic工作组的每一个人,他们不知疲倦地辩论和设计Quic。工作组由来自许多不同背景的众多个人组成,他们在相对较短的时间内制定了一项真正了不起的议定书。