目前BIGO在全球各地建了近百个IDC节点,旗下Bigo Live,Likee,imo等APP为全球150个国家的4亿多用户提供音视频服务。承载的用户来自4,500多家运营商并以移动无线网络接入为主。无线接入的用户网络情况非常的复杂多变,例如,印尼WiFi用户较4G用户体现高丢包易波动,印度4G用户较wifi用户体现高延迟高抖动,而且欠发达地区还存在Qos限流情况,所以如何在网络限流严重呈现小水管、丢包率高、容易拥塞和抖动等环境下提升用户的接入体验,是我们面临的难题。
TCP最初是为具有可预测链接的有线网络而设计的,无线网络更容易受到干扰和信号衰减的损失,例如,WiFi网络容易受到微波,蓝牙和其他类型无线电波的干扰。蜂窝网络受信号损失(或路径损失)的影响,与有线相比,它们导致更高的或易变的往返时间(RTT)和数据包丢失,导致TCP容易出现带宽和丢包的间歇波动,造成bufferbloat现象。
一、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确认等机制实现了数据包的可靠传输。
二、BIGO QUIC/TCP混合移动传输协议栈
1、QUIC协议栈的集成
图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 移动传输协议栈多协议优化
图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实验速率收益
四、0-RTT连接率优化
基于TCP的TLS 1.3需要配合TCP FastOpen(TFO)才能实现0-RTT完成加密握手。TCP FastOpen成功建连需要客户端、链路上的所有路由器、服务器的全方面支持,否则可能因为无法识别带TFO选项及数据段的SYN包而失败。我们在北美地区进行了TFO试验,能够启用TFO的移动客户端终端比例仅有约40%,最终整体TFO成功比例仅占总任务数约15%。相比之下,QUIC可以在UDP包中一次携带加密与握手信息,实现0-RTT的成功率更高。
图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连接率趋势图
五、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拥塞控制优化
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拥塞算法速率对比
七、基于数据驱动的QUIC参数配置优化
之所以引入QUIC协议,有一点便是其优秀的传输框架,包括了很多配置选项与算法选项,可以根据自身的实际情况进行调整。结合BIGO强大的AB配置平台,经过反复AB实验验证与分析,对不同地区和网络的用户针对性的进行了参数调整。调整到的参数如下表所示:
参数/选项 | 说明 |
STARTUP优化 | 判断退出startup的机制 |
判断退出startup时保持带宽稳定不再增长的RTT数 | |
慢启动阶段的pacing_gain | |
初始拥塞窗口大小 | ICWND,初始一次性可发送数据量。 |
Drain阶段参数 | 调整Drain阶段的pacing gain |
Probe_BW阶段参数 | probeBW mode下cwnd_gain参数可配。 |
ProbeRTT阶段参数 | 调整Probe_rtt阶段的cwnd |
调整进入Probe_rtt的周期、条件 | |
LossDetectionType | 丢包检测算法 |
ACK回复相关 | 接收端ACK的机制、条件 |
ack_frame的更新 | |
算法相关 | 增加pacing_rate上限设置 |
优化带宽更新方式、加速带宽更新 |
八、总结
目前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) 回帖