CDN傳輸加速—QUIC在短視頻加速上的技術落地

導語:QUIC (Quick UDP Internet Connection遍希,快速UDP互聯(lián)網連接) 是一個新的基于UDP的多路復用且安全的傳輸協(xié)議。它從頭開始設計,完全棄用了TCP,使用UDP作為底層傳輸協(xié)議。QUIC提供了等價于HTTP/2 的多路復用和流控了赌,等價于 TLS 的安全機制,及等價于 TCP的連接語義玄糟、可靠性和擁塞控制勿她。據國際互聯(lián)網工程任務組(The Internet Engineering Task Force,簡稱 IETF )消息阵翎,HTTP-over-QUIC 實驗性協(xié)議將被重命名為 HTTP/3逢并,并有望成為 HTTP 協(xié)議的第三個正式版本。

本文將介紹QUIC協(xié)議在CDN技術上郭卫,騰訊多媒體的應用落地砍聊,以及相比于TCP所帶來的極快的優(yōu)化體驗,并嘗試分析QUIC到底快在哪里贰军?

1玻蝌、背景

在現有物理資源的情況下,CDN海外機房回源词疼、回傳延遲奇高俯树,RTT最高將近500ms,TCP丟包率和成功率表現不盡人意贰盗,一個大視頻分片的上傳下載需要到2秒級许饿。而QUIC的特性在網絡傳輸,尤其是弱網情況下舵盈,效果相比TCP好很多陋率。多段256 NACK、更加激進的Loss Detection丟包探測和重傳機制秽晚、以及0-RTT的握手建立瓦糟,使其相比TCP的傳輸延遲大大降低。

2赴蝇、封裝QUIC Client SDK

QUIC運行在用戶空間狸页,底層使用UDP作為傳輸協(xié)議〕对伲客戶端側主要涉及QuicConnection芍耘、QuicStream、QuicSession三個核心功能類熄阻。

QuicConnection:負責管理QUIC連接斋竞,創(chuàng)建Connectionid,完成QUIC的握手(1-RTT/0-RTT)秃殉,確保連接建立坝初。

QuicSession:會話管理,管理QUIC整個會話的生命周期钾军。包括QuicConnection鳄袍、各種定時器Alarm、以及多Stream的生命周期等吏恭。

QuicStream:QUIC真正進行數據傳輸的媒介拗小,支持多個QuicStream并發(fā)傳輸,Stream之間的數據丟包重傳等互不影響樱哼,真正消除TCP協(xié)議的隊頭阻塞缺陷哀九。

QUIC協(xié)議在應用層實現了原本TCP幾乎所有的特性:傳輸窗口、ACK搅幅、多路復用阅束、Loss Detecion、流量控制茄唐、擁塞控制等等息裸,非常復雜。所以在工程實現上我抽取了chromium的net庫等沪编,重載QuicStream呼盆、QuicSession等,封裝成易于理解的QUIC Client SDK漾抬,提供quic_socket宿亡、quic_connect、quic_send纳令、quic_recv等開發(fā)者比較習慣的socket使用方式API挽荠。

QUIC Client SDK

2、QUIC Client在MCP++框架上的應用

MCP++框架主要是DCC模塊負責對外的請求下載等平绩,在CDN上的應用的話圈匆,Front節(jié)點的回源、回傳都需要通過DCC去下載和上傳捏雌。

1)跃赚、QUIC由于其復雜的特性實現,運行在應用層的協(xié)議棧,需要大量的CPU計算纬傲。

2)满败、以及QUIC Client自成一體的UDP Socket收發(fā),DCC原本的epoll_wait單線程模型無法支持叹括,很難改造算墨。

故而決定采用 DCC線程 + QUIC線程 的模型支持QUIC協(xié)議,QUIC Client線程保持高度的自治汁雷,請求與響應皆自我完善净嘀。DCC原本的連接管理,CRawCache等需要自己實現侠讯。

圖2挖藏、MCP DCC與QUIC交互

圖2所示,DCC與QUIC交互主要有兩個流程厢漩,不破壞現有DCC框架:

1膜眠、send_mq_request_by_quic負責將來自mq的請求發(fā)給QUIC,由quic創(chuàng)建UDP socket發(fā)送出去袁翁。

2柴底、handle_network_recive_quic負責從隊列queue里取出QUIC接收完處理后的響應消息。

3粱胜、QUIC請求流程柄驻,以及失敗回退到TCP機制

由于QUIC底層通過UDP進行連接,在大規(guī)模服務場景下焙压,幾萬臺機器所處不同的運營商和網路環(huán)境鸿脓,無法保證各種中間設備UDP和端口都可用。所以在設計時不能完全依賴UDP可信涯曲,要考慮失敗回退TCP機制野哭。

DCC與QUIC的交互有send_mq_request_by_quic, handle_network_recive_quic發(fā)送和接收兩種場景幻件,分為發(fā)送失敗和接收失敗拨黔。

DCC->QUIC請求流程:

圖3、QUIC請求與回退流程

1. epoll_wait接收來自MCD的管道m(xù)q事件绰沥。

2. 判斷請求QUIC or TCP篱蝇,用QUIC 則send_mq_request_by_quic。

3. 判斷當前要請求的flow連接是否已回退到TCP徽曲,已回退的話這里直接走TCP零截。

4. QUIC,GetQuicConn(flow)獲取QUIC連接id秃臣,連接存在直接請求涧衙,不存在quic_connect()發(fā)起握手創(chuàng)建連接。

5. connect失敗(直接返回失敗,有些場景不會直接返回失敗)弧哎,flow連接回退到TCP(后續(xù)該連接其他消息30分鐘內走TCP)雁比,當前請求消息通過TCP重試。

6. connect成功傻铣,quic_send()發(fā)送數據:

a. 發(fā)送成功枷遂,SUCCESS流程結束数冬,異步等待queue響應。

b. 發(fā)送失敗俯画,flow連接回退到TCP蜕径,當前請求消息通過TCP重新嘗試两踏。

c. Stream busy,QUIC所有Stream都處在忙狀態(tài)兜喻,連接不回退梦染,只有當前請求使用tcp發(fā)送。

QUIC->DCC響應流程:

圖4朴皆、DCC接收QUIC響應流程

1帕识、 QUIC接收校驗完畢check_complete后,將響應消息入隊列queue遂铡。

2肮疗、DCC線程send_mq_request_by_quic從隊列Dequeue 取出響應消息。

a. QUIC_SUCCESS扒接,將響應消息enqueue 發(fā)給mcd伪货。

b. CONN_ERROR,連接中斷钾怔,將quic傳來的消息進行TCP重發(fā)碱呼,flow連接回退到TCP。

0-RTT場景下宗侦,quic_connect()發(fā)出去CLHO后client端即認為連接成功愚臀,調用quic_send()發(fā)送數據(數據緩存在QUIC底層buff), 實際握手可能會超時失敗矾利。OnConnectionClose 失敗后需要通過queue通知DCC線程做相應的處理姑裂。

4、0-RTT

QUIC比TCP快的一個很大特點是其握手使用了更少的RTT梦皮,甚至達到0-RTT握手炭分,直接進行數據傳輸,相比TCP大大減少了三次握手的等待時間剑肯。而我們在CDN上的應用更進一步捧毛,front->zone的分布式集群所有機器之間的請求,除了第一次,以后均可以實現0-RTT建鏈呀忧。

圖5师痕、QUIC 0-RTT

背景:QUIC handshake握手階段服務端REJ時會下發(fā)server_config和token給客戶端《耍客戶端下次握手時胰坟,如果攜帶上上次下發(fā)的server_config和token到服務端,服務端驗證通過泞辐,即可實現0-RTT笔横。

在當前的CDN架構上要實現0-RTT,有幾個問題需要解決:

問題:

問題1. 服務端front有多個ccd進程咐吼,每個進程生成的server_config都不一樣吹缔,客戶端攜帶上次的server_config請求到其他ccd進程時锯茄,服務端校驗不通過厢塘,無法0-RTT肌幽?

問題2. 客戶端ip不是固定的晚碾,4G/WIFI切換時每次都會變換ip喂急,服務端下發(fā)的token融合了客戶端的ip格嘁,客戶端的ip變化時,攜帶的token服務端校驗不通過煮岁,無法0-RTT讥蔽?

問題3. 服務端ip對于客戶端來說不是固定的,服務端是一個集群画机,請求新的服務器ip時,如果當前client沒有請求過該server_id步氏,本地沒有緩存過新server的cache(server_config等)响禽,就無法實現0-RTT荚醒。

解決方案:

解決1:服務端所有front集群固定生成同一個server_config_id芋类。

解決2:服務端關閉token驗證開關,QUIC提供關閉驗證的開關界阁,在應用層即可關閉侯繁。

解決3:客戶端每次構建新的請求連接時使用相同的server_id(host,port)。Server_id是緩存在客戶端本地泡躯,用來指引cache的key贮竟, 對于客戶端來說,這相當于把對端所有server集群看成同一個server咕别,對同一個server進行下次握手,就會直接發(fā)起full CLHO消息惰拱。服務端那邊校驗server_config通過雌贱,就能建立新的連接了偿短。

5欣孤、QUIC對比TCP的優(yōu)化效果

線上灰度觀察效果翔冀,QUIC優(yōu)化效果明顯导街。尤其是在弱網下纤子,傳輸時延大大降低:

a)、國內以長沙電信為例控硼,回源延時219ms -> 88ms,優(yōu)化效果能達到59.8%艾少,回傳原本延時就比較低了,延時優(yōu)化效果也能達到25%缚够。

b)、海外以美國機房為例谍椅,RTT比較高的場景196ms,QUIC的回源回傳效果更加明顯1.3s->339ms雏吭,優(yōu)化率達到73.9%。

6杖们、QUIC快在哪里?

QUIC的提升效果表現如此的好摘完,究竟比TCP快在什么地方呢姥饰?TCP協(xié)議經過幾十年的發(fā)展孝治,可以說構建了整個互聯(lián)網的基礎列粪。Google為了開發(fā)QUIC做了很多工作,基本上把整個TCP的協(xié)議棧都重新實現了一遍(取其精華篱竭,修復缺陷)。嘗試分析一下:

1. 0-RTT

TCP的三次握手會帶來必定的1-RTT消耗掺逼,在網絡狀況比較好的情況下,大部分的消耗可能都來自業(yè)務吕喘,不覺得RTT耗時很多赘那。但是在網路狀況差的情況下(比如上面的美國),1個RTT就帶來196ms的延時募舟,使用QUIC優(yōu)化后,可以看出整體耗時只有339ms闻察,所以0-RTT對于秒開業(yè)務來說是一個很重要的特性。

2. QUIC Stream多路復用 — TCP 隊頭阻塞

QUIC支持多路復用辕漂,QUIC的底層UDP不進行排序和確認,只負責傳輸钉嘹,ACK、確認跋涣、排序等都在QUIC進行缨睡。TCP當有多個流同時傳輸時陈辱,如果某個流發(fā)生了丟包奖年,其他流需要等待其重傳排序完成才能繼續(xù)傳輸,因為TCP的滑動窗口只有一個拾并,隊頭阻塞無法避免。而QUIC的多個Stream之間重傳嗅义、排序等互不干擾,有stream級別的流控窗口隐砸,真正從傳輸層解決隊頭阻塞的問題。

從客戶端和CDN服務器的統(tǒng)計上看到季希,同一連接多個Stream同時傳輸的場景非常頻繁幽纷。而去除了隊頭阻塞的QUIC延時比TCP低就很明顯了,并且在弱網丟包率高場景下友浸,表現更好。

3. Up to 256 NACK ranges偏窝,支持256分段ACK

TCP每次只會ACK一個數據包收恢,當滑動窗口用盡之后祭往,只能等待新的ACK到來才能繼續(xù)發(fā)送新數據包伦意。就算開啟了SACK硼补,最多也只能ACK三個包。

QUIC最大支持ACK 256個數據包已骇,支持分段ACK离钝。就算某個ACK包丟失褪储,后續(xù)其他包的ACK也能帶上之前ACK過的包號。

4. Loss Detection丟包探測

QUIC在TCP的經驗之上重新構建了一種新的丟包探測機制:FR快重傳乱豆、ER早期重傳吊趾、RTO宛裕、TLP论泛、F-RTO揩尸,和TCP相比很大不同屁奏。表現為更為激進的丟包發(fā)現和重傳策略:比如如果收到最大的ACK包號大于3就判斷丟包進行FR重傳岩榆;而TCP需要收到連續(xù)三個重復的ACK才判斷丟包進行快重傳坟瓢。

7勇边、總結

本文介紹當前主流的基于chromium的QUIC Client SDK的架構折联,以及其在騰訊MCP++框架上的工程落地。詳細介紹了MCP++框架上的 DCC+QUIC 多線程lib方案诚镰,和QUIC回退到TCP的保障機制奕坟,另外簡單介紹了下全面?0-RTT 在 Front->zone 上實現存在的問題和解決方案。通過在線上使用QUIC與TCP的實際對比效果月杉,以及QUIC多路復用、256NACK等優(yōu)秀特性苛萎,國內各大廠商紛紛在研究和應用QUIC協(xié)議,證明QUIC是一個潛力很大的技術首懈。IETF已經將HTTP over QUIC重命名為HTTP3,隨著下一代HTTP3協(xié)議的普及究履,QUIC將應用的更加廣泛滤否。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末最仑,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子泥彤,更是在濱河造成了極大的恐慌,老刑警劉巖吟吝,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異剑逃,居然都是意外死亡,警方通過查閱死者的電腦和手機蛹磺,發(fā)現死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萤捆,“玉大人裙品,你說我怎么就攤上這事俗或。” “怎么了蕴侣?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昆雀。 經常有香客問我辱志,道長,這世上最難降的妖魔是什么揩懒? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮已球,結果婚禮上,老公的妹妹穿的比我還像新娘智亮。我一直安慰自己,他們只是感情好阔蛉,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著状原,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颠区。 梳的紋絲不亂的頭發(fā)上削锰,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天毕莱,我揣著相機與錄音,去河邊找鬼朋截。 笑死磨澡,一個胖子當著我的面吹牛质和,可吹牛的內容都是我干的。 我是一名探鬼主播饲宿,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瘫想!你這毒婦竟也來了?” 一聲冷哼從身側響起国夜,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎车吹,沒想到半個月后筹裕,有當地人在樹林里發(fā)現了一具尸體窄驹,經...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡朝卒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年乐埠,在試婚紗的時候發(fā)現自己被綠了抗斤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丈咐。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖棵逊,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情歹河,我是刑警寧澤掩浙,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布秸歧,位于F島的核電站厨姚,受9級特大地震影響键菱,放射性物質發(fā)生泄漏谬墙。R本人自食惡果不足惜经备,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一拭抬、第九天 我趴在偏房一處隱蔽的房頂上張望侵蒙。 院中可真熱鬧造虎,春花似錦纷闺、人聲如沸算凿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浸卦。三九已至署鸡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間靴庆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工撒穷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留匣椰,地道東北人端礼。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓禽笑,卻偏偏與公主長得像蛤奥,于是被迫代替她去往敵國和親佳镜。 傳聞我的和親對象是個殘疾皇子凡桥,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容