首页 > BIGO 技术 | QUIC协议在BIGO的实践与优化
头像
BIGO校招助手
发布于 2020-12-15 18:14
+ 关注

BIGO 技术 | QUIC协议在BIGO的实践与优化


*本文转载自 BIGO技术 公众号,对BIGO技术感兴趣的同学可以关注了解更多内容~




目前BIGO在全球各地建了近百个IDC节点,旗下Bigo Live,Likee,imo等APP为全球150个国家的4亿多用户提供音视频服务。承载的用户来自4,500多家运营商并以移动无线网络接入为主。无线接入的用户网络情况非常的复杂多变,例如,印尼WiFi用户较4G用户体现高丢包易波动,印度4G用户较wifi用户体现高延迟高抖动,而且欠发达地区还存在Qos限流情况,所以如何在网络限流严重呈现小水管、丢包率高、容易拥塞和抖动等环境下提升用户的接入体验,是我们面临的难题。

TCP最初是为具有可预测链接的有线网络而设计的,无线网络更容易受到干扰和信号衰减的损失,例如,WiFi网络容易受到微波,蓝牙和其他类型无线电波的干扰。蜂窝网络受信号损失(或路径损失)的影响,与有线相比,它们导致更高的或易变的往返时间(RTT)和数据包丢失,导致TCP容易出现带宽和丢包的间歇波动,造成bufferbloat现象。

为了解决这些难题,我们采用了QUIC协议,它是通过UDP实现的流多路复用现代传输协议,使我们能够更好地做传输控制协议优化,提供双端加速效果,提升吞吐和抗丢包能力。

一、QUIC选型及结构

QUIC的开源实现有很多,从最早的Google QUIC(gQUIC)、QUIC-go、ngtcp2到后续的mvfst、quicly、Quiche等等。我们从并发性能、网络传输性能以及协议实现成熟度等方面对QUIC开源实现进行了全面的评估。其中,gQUIC和quicly的并发性能最优,两者中gQUIC发展时间更长,有完善的拥塞控制及丢包恢复算法,在网络传输算法及协议实现成熟度方面显著优于quicly。因此我们最终选择了gQUIC作为QUIC协议栈的研发基础,在此基础上进行优化迭代。

gQUIC的主要层次结构可分为SPDY/HTTP2(应用协议层)、Stream、Session、Connection。


图1 Google QUIC层次结构

gQUIC中最上层实现了SPDY/HTTP2协议以对接使用QUIC Stream实现多路复用,在不同的应用场景下可以对该层进行替换,以实现多种协议与QUIC Stream的对接。

Stream层是多路服用中对接应用的流接口层,接收到应用数据后会在Stream中形成流式缓存,类似TCP的滑动窗口机制对待发送、已发送未确认及已确认的数据进行管理。

Connection层是QUIC的核心连接管理层,而其管理的数据,则是已经分化后的按照发送时间排序的包,而不在是Stream中的数据流;Connection层以模块形式接入拥塞控制、重传、丢包检测、ACK确认等机制实现了数据包的可靠传输。

Session层则在Stream与Connection之间,管理多个Stream流的发送顺序,以及对于数据包与Stream流的映射进行管理。

二、BIGO QUIC/TCP混合移动传输协议栈

1、QUIC协议栈的集成

BIGO移动传输协议栈需要承载多种应用层协议的通信传输,因此并没有直接使用Cronet库作为底层传输库;而是将QUIC中的Stream层以下结构拆分出来,并通过Socket抽象封装,与TCP/TLS传输协议栈一同为上层应用提供无感知的多协议通信传输通道。

图2 BIGO移动传输栈客户端结构

我们优先在全球上传业务中启用了QUIC协议传输,并通过A/B实验平台进行对比,结果表明整体速率提升效果显著。在印尼地区,WIFI用户比重大,链路质量受到限流约束较小,使用QUIC协议带来的速度提升最为显著;印度及全球整体的移动用户比例较高,平均也有超过12%的速度提升;上传成功率提升2%,提升用户人均生产。

地区及网络

实验名

上传速度收益

印尼

QUIC上传

18.2%

TCP上传

 

印度

QUIC上传

12.82%

TCP上传

 

全球其他地区

QUIC上传

14.79%

TCP上传

 

表1 QUIC上传A/B实验对比速度

2、QUIC移动客户端库体积优化

在集成QUIC协议栈的时候,发现客户端库体积增加过多,给集成上线造成了难题。我们对QUIC客户端协议栈进行了分析,对于客户端协议栈来说,新增的加密套件、QUIC协议的服务端组件以及部分基础库组件对于我们来说是非必要的,我们从这一角度入手进行了优化。对于加密套件部分,我们基于客户端系统加密接口进行了转换及适配替代了QUIC协议栈依赖的boringssl加密方法及接口,实现加密套件的裁剪;对于服务端组件以及部分基础库组件,通过增加编译条件宏进行屏蔽,使用C++基础库进行替换以及优化编译参数等方法达成了裁剪目标。优化后整体QUIC协议栈在客户端库中所占体积从1.1MB减小至500余KB。

我们在BIGO移动传输协议栈增加了灵活的请求重试与协议切换机制,来避免TCP/UDP协议传输因为网络QoS限制、协议封禁等问题,造成传输效率严重受限。在QUIC协议集成并大规模覆盖后,通过分析线上用户传输数据,我们发现配置QUIC协议优先的用户中,在不同国家及地区约有6~10%的任务最终使用TCP协议进行传输。这表明UDP协议的QoS限制问题在部分地区比较突出,这促使我们设计了多协议优选机制来优化部分地区的传输质量体验。

三、BIGO 移动传输协议栈多协议优化

BIGO移动传输协议栈在TCP/TLS及QUIC协议之上封装了一层类Socket API供应用层调用,通过Socket API实现协议解耦合,为传输协议栈进行多协议择优选择提供了极大的便利。在应用层发起建连请求后,传输协议栈同时发起QUIC与TCP/TLS建连,依据建连时间选择最优的传输通道发起请求。在多协议优选模式中,可配置QUIC优先或TCP优先。需要特别注意,在QUIC优先模式下,因为QUIC可以使用0-RTT实现快速建连,此时并没有任何数据交换,无法判定当前网络对UDP是否存在降级;实际上QUIC使用0-RTT时客户端还是会与服务端进行一次密钥交换,只是初始数据使用缓存的服务端公钥进行加密即可。

图3 多协议模式传输流程图

如上图所示,BIGO传输栈多协议优选模式中,为了避免QUIC 0-RTT机制使得传输栈误以为QUIC更快完成握手,在QUIC完成密钥交换前,传输协议栈在使用QUIC协议发送应用请求的同时也会进行缓存;若QUIC优先完成密钥交换,则可关闭TCP连接,若TCP优先完成建连,可以依据配置的QUIC与TCP权重,等待一定的时间(可以依据TCP建连的RTT时长动态配置等待时长,例如我们在印度地区配置了等待1倍RTT时长),超时则关闭QUIC连接,转为使用TCP发送请求数据。

地区及网络

实验名

上传速率收益

印尼

双协议链路优化

1.71%

QUIC单协议模式

 

印度

双协议链路优化

2.02%

QUIC单协议模式

 

全球其他地区

多协议链路优化

4.60%

QUIC单协议模式

 

表2 QUIC优先多协议优选上传A/B实验速率收益

我们也在全球多个国家及地区进行了A/B实验对比,可以看出,多协议优化在不同的网络环境适应性有所不同。印尼地区WIFI网络用户比重大,受到UDP QoS限制的影响相对较小,因此多协议优化不显著;印度及全球其他地区移动网络用户比例较大,多协议优化速率提升更为显著。

四、0-RTT连接率优化

基于TCP的TLS 1.3需要配合TCP FastOpen(TFO)才能实现0-RTT完成加密握手。TCP FastOpen成功建连需要客户端、链路上的所有路由器、服务器的全方面支持,否则可能因为无法识别带TFO选项及数据段的SYN包而失败。我们在北美地区进行了TFO试验,能够启用TFO的移动客户端终端比例仅有约40%,最终整体TFO成功比例仅占总任务数约15%。相比之下,QUIC可以在UDP包中一次携带加密与握手信息,实现0-RTT的成功率更高。

我们使用的gQUIC版本与当前IETF QUIC标准版本在TLS加密方面有所差别,但在0-RTT的实现理念上与TLS 1.3是一脉相承的。

图4 QUIC初始建连第一个RTT客户端无数据发送

客户端在首次建连握手中获取到包含初始公钥的ServerConfig并将该配置信息缓存下来,这与TLS 1.3中对Session Ticket的处理是类似的。首次建连过程中,第二个RTT会依据ServerConfig中的密钥套件配置及初始公钥生成初始加密密钥,并使用该密钥加密握手包,握手包包含为本次连接生成的客户侧密钥的公钥;服务端收到该握手包后,会再为本次连接生成一个服务侧密钥,配合客户端公钥最终生成前向安全的加密密钥。同时客户端在第二个RTT发送握手包后,也可以使用初始加密密钥发送数据,使用初始加密密钥发送的数据被认为是非前向安全的。


图5 QUIC二次建连第一个RTT客户端可发送数据

客户端第二次与同一个服务端第二次建连时,就可以直接使用缓存的ServerConfig,其过程与第一次建连过程中第二个RTT基本类似,在此不再赘述。

0-RTT需要第二次与同一服务器进行连接才能够生效,出于负载均衡的考虑,客户端会随机在多个下载服务端进行选择,并且出于安全考虑ServerConfig仅保存在内存中,App重启后即清除,导致0-RTT成功率不高,QUIC快速加密握手的优势不显著。


图6 BIGO QUIC ServerConfig同步流程

在BIGO的媒体传输系统双端自主可控的前提下,我们设计实现了QUIC ServerConfig预取机制。在后端中台配置了ConfigManager模块来生成ServerConfig,下载服务器启动后,可以定期从ConfigManager获取统一的ServerConfig。同时用户登陆的Gateway也会缓存一份,在用户登陆时下发ServerConfig配置,传递给传输栈中的QUIC模块使用。这样客户端在获取到统一的ServerConfig后,第一次与任意服务器建连即可使用ServerConfig发起0-RTT握手及请求。


图7 BIGO QUIC下载0-RTT连接率趋势图

在Imo的点播文件下载及群文件共享下载业务中启用了QUIC ServerConfig预取机制,从线上数据反馈看来,随着实验逐步放量整体0-RTT连接率从82%提升至91.5%。

五、QUIC负载优化

相比TCP协议,QUIC在应用层实现的传输控制方法为针对不同场景的控制优化提供了便利,但高并发服务在负载方面比TCP协议有较大的劣势。

BIGO网络传输技术团队在部署QUIC的过程中对QUIC负载问题进行了分析及优化。我们分析QUIC传输协议栈性能问题主要来源有:1)ACK及数据处理流程分散,数据处理效率较低,2)Linux内核的UDP包发送效率不高,3)gQUIC协议栈整体复杂度较高,例如发送逻辑从数据准备到数据发送在用户态函数嵌套过多。

1. 由于QUIC协议的发送数据缓存与ACK处理分别在Stream层与Connection层,这导致接收ACK确认数据后需要访问Stream才能获得待发送数据,当QUIC传输协议栈并发访问量较高时,高频次的ACK处理与Stream层访问大幅降低了数据发送整体效率。对于该问题,我们通过解除ACK处理与Stream层访问的逻辑耦合性,将Stream层访问依据ACK接收频次进行一定程度的聚合,以此提高数据发送的整体效率。

2. 为了解决Linux内核UDP发包效率问题,QUIC发送底层接口采用sendmmsg和UDP GSO,同等负载下UDP数据吞吐量提升15%。

3. 针对gQUIC协议栈整体复杂度较高的问题,我们采用Facebook开源二进制优化和布局工具BOLT对QUIC上传/下载服务器进行优化。


图8 优化前后CPU负载火焰图对比

经过上述优化后,QUIC下载服务器统计反馈在高并发下负载相比优化前降低50%左右。从火焰图对比可以看出UDP数据发送的CPU占用显著减少,同时包发送逻辑与收报处理更加分离,数据发送函数嵌套深度大幅减少。

六、QUIC拥塞控制优化

gQUIC在拥塞控制上集成了BBR,在丢包检测上比Linux内核更早提供了尾丢包探测、自适应丢包探测等机制。BIGO网络传输技术团队在此基础之上,针对我们在全球服务中发现的问题,对于QUIC传输控制,特别是拥塞控制进行了优化,提升了原版BBR在全球复杂网络中的吞吐与抗丢包能力:

1. 抗丢包优化:根据丢包率动态调整pacing gain来调整发送速率以提升抗丢包能力。

2. RTT抗抖动优化:通过统计、采样等方式优化minRTT测量不准的问题;借用packet train思想探测数据接收率来统计真实的带宽值。

3. 带宽抖动优化:通过随机化probe_bw阶段平稳发送周期个数,提升BBR感知带宽变化的能力。

4. ACK乱序优化:通过修正乱序ACK来重新计算ACKRate,进而保证带宽计算的稳定性。

5. 流量监管优化:引进Token bucket policer优化,及增加多轮探测,准确的检测到当前的限速状态,调整发包节奏。


图9 QUIC协议BBR拥塞算法速率对比

经过优化后,BIGO BBR相比Google BBR在抗丢包、抗抖动能力方面全面提升,在弱网速率测试中,相比Google BBR,在一些常规网络场景下有2%~3%的速率提升,而在大于20%丢包和大于100ms抖动场景下,Google BBR则无法正常工作,BIGO BBR能正常的稳定发包。

七、基于数据驱动的QUIC参数配置优化

之所以引入QUIC协议,有一点便是其优秀的传输框架,包括了很多配置选项与算法选项,可以根据自身的实际情况进行调整。结合BIGO强大的AB配置平台,经过反复AB实验验证与分析,对不同地区和网络的用户针对性的进行了参数调整。调整到的参数如下表所示:

参数/

说明

STARTUP优化

判断退出startup的机制

判断退出startup时保持带宽稳定不再增长的RTT

慢启动阶段的pacing_gain

初始拥塞窗口大小

ICWND,初始一次性可发送数据量。

Drain阶段参数

调整Drain阶段的pacing gain

Probe_BW阶段参数

probeBW modecwnd_gain参数可配。

ProbeRTT阶段参数

调整Probe_rtt阶段的cwnd

调整进入Probe_rtt的周期、条件

LossDetectionType

丢包检测算法

ACK回复相关

接收端ACK的机制、条件

ack_frame的更新

算法相关

增加pacing_rate上限设置

优化带宽更新方式、加速带宽更新

表3 QUIC协议调整参数与说明

八、总结

目前bQUIC已经在BIGO全球机房都已经部署,根据全球IDC机房的前端网络探测质量和全球实时调度算法,应用于短视频上传录制和下载播放,以及实时通信服务中的文件传输,日均承载生产上传和下载播放近亿次。由于bQUIC经过优化之后负载和服务成本依然有些偏高,我们的团队正在积极优化改进,比如采用dpdk加速kernel bypass方案,或者xdp加速,提升单机负载能力。在传输优化上依托大数据及机器学习驱动,通过采集传输类型、接入运营商、网络类型、用户地理位置、网络时延、丢包率、使用时间段等维度数据,作为分析网络环境状况的原始素材,对这些数据做网络流量和拥塞情况的大数据分析,持续优化传输算法,进一步提升网络吞吐和抗丢包能力;不论其网络或区域如何,都能提供更方便及无缝地数据传输,为全球用户提供稳定高效地传输体验。

 

Reference:

https://quicwg.org/base-drafts/draft-ietf-quic-tls.html

https://quicwg.org/base-drafts/draft-ietf-quic-transport.html

https://squeeze.isobar.com/2019/04/11/the-sad-story-of-tcp-fast-open/

https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/46403.pdf The QUIC Transport Protocol:Design and Internet-Scale Deployment

https://www.chromium.org/quic google quic

https://lwn.net/Articles/752184/ UDP GSO in Linux Kernel

https://github.com/google/bbr Google BBR

https://tlswg.org/tls13-spec/draft-ietf-tls-tls13.html tls 1.3 The Transport Layer Security (TLS) Protocol Version 1.3






全部评论

(0) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

近期热帖

历年真题 真题热练榜 24小时
技术(软件)/信息技术类
查看全部

近期精华帖

热门推荐