Facebook如何将QUIC应用于数十亿流量传输

Stella981
• 阅读 704

Facebook如何将QUIC应用于数十亿流量传输

随着IETF很快完成QUIC标准定稿,越来越多的企业和开发者投入到QUIC开发实现与部署中。阿里巴巴实现了XQUIC;B站、快手在2019年就公开了QUIC的应用实践;Akamai等CDN服务商则很早就开始拥抱QUIC,并提供相应的支持。本文来自Facebook的工程博客,详细介绍了Facebook是如何将其3/4的流量切换到QUIC上的。

Posted by Matt Joras,Yang Chi

Translated by  周玉镧

Article proofread by 刘连响

URL:https://engineering.fb.com/networking-traffic/how-facebook-is-bringing-quic-to-billions/

正文字数:3551  阅读时长:7分钟

Facebook正在使用QUIC取代互联网几十年来一直沿用的默认协议,这是我们最新的网络协议优化策略,同时也是最激进的一步,目的还是为了进一步提高我们的服务的用户体验。

今天,QUIC和HTTP/3在我们的互联网通信中使用率超过75% (我们将QUIC和HTTP/3统称为QUIC) 。QUIC已经显著地改善多个指标,包括请求错误、尾延迟 (Tail Latency) 、响应头大小以及各种其他影响我们应用程序用户体验相关的参数。

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

  • 什么是QUIC和HTTP/3呢?

从广义上讲,QUIC替代了传输控制协议_(TCP)_,后者是互联网通信的主要协议之一。QUIC最初由谷歌公司内部研发,称为GoogleQUIC,或gQUIC,于2015年提交给IETF。从那之后,更广大的IETF社区对其进行了重新设计与改进,形成了一个新的协议,也就是我们现在所说的QUIC。

HTTP/3是HTTP的新一代迭代,它是基于网络的应用程序和服务器之间通信的标准协议。综合Facebook、谷歌和IETF社区数十年来在互联网上运行协议获得的最佳实践经验和教训,_QUIC和HTTP/3共同代表了最新且最强大的以互联网为中心的协议_。

QUIC和HTTP/3整体优于TCP和HTTP/2,后者则跑赢了TCP和HTTP/1.1。TCP和HTTP/2首先引入了流多路复用的概念,在同一进程中,允许单个网络连接服务多个数据流。QUIC和HTTP / 3在此基础上更进一步,通过避免TCP可怕的队头阻塞 (队头阻塞时,丢失的数据包发生阻塞同时导致连接上的所有流变慢) ,从而使得流真正独立。

QUIC采用了最先进的丢失恢复技术,在恶劣的网络条件下,这能使得它在大多数情况下性能跑赢TCP协议实现。TCP也容易僵化,因为防火墙等网络中间件对数据包的格式做了假设,TCP协议很难进行升级,QUIC通过完全加密功能避免了这个问题,使得协议的可扩展性走向最佳,同时保证将来可以进行改进。QUIC还可以通过QLOG (一种专门为QUIC设计的基于JSON的跟踪格式) 来检测、观察和可视化展示传输行为。

  • 以经验为导向的协议开发

Facebook开发了自己的QUIC实现,我们称之为mvfst,以便在我们自己的系统上快速测试和部署QUIC。我们有编写和部署自己的协议实现的经验,首先部署我们的HTTP客户机/服务器库Proxygen,紧接着是Zero协议,最后是Fizz_(我们的TLS1.3实现)_。

Facebook应用程序运用Fizz和Proxygen通过Proxygen Mobile与服务器进行通信。我们还为TLS开发了一个名为delegated credentials的扩展程序,提供两方面安全解决方案,一方面可用于保护TLS上的证书和DNS,另一方面也可用于加密和验证TLS上的web流量。

  • 从头开始开发和部署新的传输协议

我们希望新协议能够与现有的软件无缝集成,并且帮助Facebook的开发人员更高效地工作。作为一个试验场,我们决定将QUIC部署在Facebook的相当一部分网络流量上,尤其包括指向Facebook的公共代理流量在内的内部网络流量。假如QUIC不能很好地处理内部流量,我们便可以确定它在更广阔的互联网上效果也不会太好。

除开能暴露错误及其他有问题的行为之外,通过这种策略,我们可以设计一种方法,使我们的网络负载均衡器对QUIC深度了解,并使得负载均衡器的零停机释放得到保证。

有了这个坚实的基础,我们开始向互联网上的用户部署QUIC。基于mvfst的设计,我们能够将QUIC支持平稳地集成到Proxygen Mobile中。

  • Facebook应用程序

_部署到Facebook应用程序是我们在互联网上使用QUIC的第一个目标。_Facebook拥有成熟的基础架构,可以让我们在向数十亿人发布应用程序之前,以有限的方式安全地推出应用程序的更新。

我们从一个实验入手,在Facebook应用程序的动态GraphQL请求中启用了QUIC。在这些请求的响应中,没有图像和视频之类的静态内容。

我们的测试表明,运用QUIC使得多个指标有所提升。Facebook用户的请求错误率下降了6%,尾延迟下降了20%,响应头大小相较于HTTP/2缩小了5%。同时这也对其他指标产生了级联效应,可以说QUIC极大地提高了用户的体验。

然而,QUIC的应用相较TCP也有倒退之处。最令人费解的是,尽管仅在动态请求时启用QUIC,然而我们发现使用TCP下载的静态内容的错误率却增加了。其根本原因是我们在将流量转换到QUIC时遇到的一个常见问题:应用程序的逻辑是,根据不同类型内容的请求的速度和可靠性,切换请求的类型和数量以处理相应的类型内容。于是乎,改进一种请求类型可能会对其他类型产生糟糕的副作用。

再如,QUIC带来的另一些麻烦,适应应用程序从服务器请求新静态内容的积极性的启发式算法将随着QUIC的使用而发生改变,当应用程序发出一个请求时,比方说,当加载News Feed的文本内容时,需要观察这个请求耗时多久,然后再决定发出多少图像/视频请求。

我们发现启发式算法策略可能对TCP比较有效,它是用任意阈值进行调整的。但是当我们切换到QUIC时,这些阈值变得不准确,应用程序可能一次发送请求过多,最终导致News Feed的加载时间进一步加长。

  • 扩大使用范围

下一步是为Facebook应用中的静态内容部署QUIC_(如:图片和视频)_。然而,在此之前,我们必须解决两个重点问题:mvfst的CPU效率以及我们的主要拥塞控制实现的有效性与BBR。

到目前为止,mvfst的设计初衷是帮助开发人员灵活开发并跟上不断变化的QUIC草案。与静态请求相比,动态请求的响应相对较小,它不需要占用大量的CPU,也不需要拥塞控制器来控制其进度。

为了解决这些问题,我们开发了性能测试工具,用以帮助我们评估CPU的使用情况并有效地运用拥塞控制器来管理网络资源。

我们在负载均衡器中综合使用了QUIC的负载测试和这些性能测试工具,取得了一些成果。一个重要的方向——例如——优化我们调整UDP数据包的效率,以保证数据传输更加平滑。为了提高CPU的使用率,我们采用了不少技术,诸如使用通用分段延后处理 (GSO) 来一次高效地发送多个UDP包。我们还对处理未确认的QUIC数据使用的数据结构和算法进行了优化。

  • QUIC针对所有内容

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

实验表明,QUIC对Facebook应用中的视频相关的指标有着革命性的影响。根据平台的不同,体现出缓冲事件间隔耗时指标的平均重新缓冲时间 (MTBR) 总体上提高了22%。视频请求的总体错误量减少了8%。视频卡顿率降低了20%。

包括元指标在内的其他几个指标,考虑到各种因素,特别是异常情况,也得到了显著改善。QUIC改善了视频观看体验,对网络条件相对较差的地区,尤其是新兴市场,产生了巨大的影响。

然而,能达到这样的成就,一路上也是困难重重。一如我们在动态内容方面的经历,我们在应用程序中发现了针对TCP行为进行调整的启发式方法。例如,iOS和Android上的应用程序有不同的机制来估计可用的下载带宽。当使用QUIC时,这些估计器有时会高估可用带宽,导致应用程序播放的视频质量高于网络所能支持的质量,从而引起视频卡顿。

我们还需要调整流控制参数并继续迭代它。流控制限制了接收者期望从发送者那里缓存到的数据量。Facebook应用程序对HTTP/2有一个静态定义的流控制限制,该限制是针对TCP进行的隐藏式优化,不过在QUIC中表现不太好。为了找到新的最优流量控制值,我们需要进行一些实验性迭代。

Facebook如何将QUIC应用于数十亿流量传输

QUIC和TCP视频加载时间之间的个体差异

  • Instagram及其他

即使是在Facebook这样丰富复杂的应用程序上,QUIC也被证明能够有效改善人们在互联网上的体验。在未来,我们计划继续利用更多QUIC的已有功能,比如连接迁移和真正的0-RTT连接创建,并致力于改善拥塞控制和损失恢复。

我们也在Instagram中部署了QUIC,使用了与Facebook部署相同的策略——先在Instagram的一小部分流量上进行测试,然后进一步大规模使用。

如今,QUIC已经部署到了Instagram的iOS和安卓版本上。Instagram的两个版本的相关指标的优化成果都达到甚至超越了我们先前在Facebook应用程序上取得的收获。

Facebook和Instagram的网页版上也启用了QUIC,随着更多的web浏览器开始支持QUIC——如最近谷歌对Chrome和苹果对Safari beta所做的改进——越来越多的用户将从中受益。

除了Instagram之外,我们相信我们有能力将QUIC的优势带到Facebook应用家族中的所有应用的每一次体验中去, QUIC最终将不仅代表Facebook的大部分互联网流量,而是代表Facebook的所有互联网流量

IETF有望在2021年某个时间点完成对QUIC协议的征求意见文档 (RFC) 的定稿。到那时候,会有更多的网站、应用程序和网络库提供通用的QUIC。 在不久的将来,像QUIC这样的新协议将是解锁互联网应用创新的关键。 对我们来说,QUIC则是一个起点,我们将继续提升人们在Facebook上的用户体验。

在Facebook内外,有太多的人共同努力促成了QUIC的成功部署。我们要感谢在过去几年中参与IETF QUIC工作组的所有成员,感谢他们对QUIC不懈地探讨与设计。IETF QUIC工作组由许多不同背景的成员组成,他们在相对较短的时间内制定出了一项真正称得上卓越的网络协议。

Facebook如何将QUIC应用于数十亿流量传输

LiveVideoStackCon 2020 北京

2020年10月31日-11月1日

点击 【阅读原文】了解更多详细信息

本文分享自微信公众号 - LiveVideoStack(livevideostack)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
刚刚好 刚刚好
2个月前
css问题
1、 在IOS中图片不显示(给图片加了圆角或者img没有父级) <div<img src""/</div div {width: 20px; height: 20px; borderradius: 20px; overflow: h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
晴空闲云 晴空闲云
2个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。 盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
1个月前
快速入门|使用MemFire Cloud构建React Native应用程序
> MemFire Cloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Wesley13 Wesley13
1年前
MySQL查询按照指定规则排序
1.按照指定(单个)字段排序 select * from table_name order id desc; 2.按照指定(多个)字段排序 select * from table_name order id desc,status desc; 3.按照指定字段和规则排序 selec
Wesley13 Wesley13
1年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表: **时辰** **时间** **24时制** 子时 深夜 11:00 - 凌晨 01:00 23:00 - 01 :00 丑时 上午 01:00 - 上午 03:00 01:00 - 03 :00 寅时 上午 03:00 - 上午 0
Stella981 Stella981
1年前
Hacker News 简讯 2020
![](https://oscimg.oschina.net/oscnet/up-3b137e2e6620f7a63f11a96485b1fb3b.png) 最后更新时间: 2020-08-26 23:00 -------------------------------------------------------------------------
Stella981 Stella981
1年前
Angular material mat
Icon Icon Name mat-icon code _add\_comment_ add comment icon <mat-icon> add\_comment</mat-icon> _attach\_file_ attach file icon <mat-icon> attach\_file</mat-icon> _attach\
Wesley13 Wesley13
1年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
#### 背景描述 # Time: 2019-01-24T00:08:14.705724+08:00 # User@Host: **[**] @ [**] Id: ** # Schema: sentrymeta Last_errno: 0 Killed: 0 # Query_time: 0.315758 Lock_
helloworld_34035044 helloworld_34035044
4个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为
helloworld_28799839 helloworld_28799839
2个月前
常用知识整理
# Javascript ## 判断对象是否为空 ```js Object.keys(myObject).length === 0 ``` ## 经常使用的三元运算 > 我们经常遇到处理表格列状态字段如 `status` 的时候可以用到 ``` vue