天天看點

QUIC簡介(一) QUIC和TCP 引用 注解

分類: LINUX

作者:henrystark [email protected]

Blog: http://henrystark.blog.chinaunix.net/

日期:20140626

本文遵循CC協定:署名-非商業性使用-禁止演繹 2.5(https://creativecommons.org/licenses/by-nc-nd/2.5/cn/)。可以自由拷貝,轉載。但轉載請保持文檔的完整性,注明原作者及原連結。如有錯訛,煩請指出。

(I am a watcher. I like thinker or creater,not follower. If you are a good follower and get the key point by learning others, don't say you own it.)

QUIC和TCP

0.寫作目的

QUIC由Google提出,基于UDP,用于加快網絡速率。常用來和基于TCP的SPDY比較。Google在傳輸層、應用層或其他方面做出的提升網絡品質的貢獻令人佩服。本篇blog将論述QUIC的起源、優缺點,以及TCP存在的問題。

1.引言

Why QUIC is necessary? 每個接觸QUIC的programmer總會這樣問。答案也很簡單:SPDY、TCP不夠好!不過這樣說太膚淺了,下面我來分析本質原因【引 1】。基于一條TCP連接配接的SPDY複用連接配接會面臨這樣的情況:當有丢包發生時,所有連接配接都将阻塞,這是由TCP的擁塞控制特性決定的【引 2 3】。丢包必須恢複,而恢複過程中,或早或晚,滑動視窗總有停等的時刻,耗費一個RTT。在廣域網上,一個RTT相當于50-100ms。相比較而言,當x條并行HTTP連接配接中,有一條丢包,隻會阻塞一條。

QUIC是和HTTP同一層的應用層協定,其核心是将丢包控制工作轉移到應用層【注 1】。由于QUIC基于UDP,可以不理會丢包,快速投遞,再用丢包恢複方法保證可靠性。除此之外,基于一條TCP連接配接的SPDY和多條并行HTTP連接配接相比,沒有優勢可言。多條連接配接中,每個連接配接都有一個擁塞視窗,不受彼此丢包影響。Google希望通過QUIC更好地處理多條連接配接下的擁塞狀況。

2.TCP的症結

以上所述其實反映了TCP基于視窗的擁塞控制政策的問題。TCP的核心在于“丢包必須恢複”,正是這種丢包恢複導緻傳輸速率降低。而除此之外,TCP擁塞控制也存在粒度不精細等問題。舉例而言,往年有一道很好的面試題:早期網絡中,為什麼螞蟻等下載下傳器比網頁下載下傳快?答案是下載下傳器使用多線程,多連接配接下載下傳,而網頁下載下傳往往使用單連接配接。也許回答到這種程度,大部分人已經滿意了。但往下問,還有更深刻的内涵:為什麼多連接配接比單連接配接快?ISP給使用者配置設定的帶寬不是固定嗎?

我想,到了這種程度,大多數人回答不出是以然來。可以從兩方面解釋:1.多連接配接下載下傳中,每個連接配接負責下載下傳不同的offset range 2.TCP基于視窗的擁塞控制不夠好,多個連接配接更具有侵略性,能占據更多的帶寬。關于第一點,學過網絡程式設計的人多多少少知道。第二點,則需要詳細解釋了。TCP用congestion window(cwnd)來控制發送速率,發送初期,cwnd二次增長,丢包時減半,之後線性增長。TCP的初始視窗為2MSS,下限為1MSS,當多條流存在時,即便丢包,視窗減幅也有限。現有使用者帶寬并不高,帶寬時延積BDP也不會很大,100MSS的cwnd足夠大了。如果有10條TCP連接配接并發下載下傳,那麼最差的cwnd之和也是10MSS,當然比隻有一條連接配接時,視窗為1MSS要好。

也許說到這種程度就可以了,但是我們還可以更深一步:為什麼TCP基于視窗的擁塞控制行為會有這樣的缺陷?怎麼改進?首先需要明确兩個概念:視窗、段,TCP中,視窗是以段(segment,MSS)為機關的,一個MSS通常為1460Bytes,cwnd就是x*MSS。再來看多流并發的問題:多連接配接下載下傳中,假設流數為n,那麼總視窗最低降為n個MSS。這對于并行下載下傳來說是優勢,因為最低視窗也很高。那麼,從反方面看呢?你覺得并發下載下傳好,是因為多流可以提升帶寬使用率,換言之,多流視窗之和沒有超過BDP。那是否存在這樣的狀況:多流最低視窗之和遠遠大于BDP?不幸的是,存在。這種狀況誕生的場景是:并發量高而BDP小的網絡,其中最典型的就是資料中心網絡。資料中心網絡具有的特征為:高帶寬、低延時、高并發、BDP小,交換機緩存有限。實際上,當多流視窗之和遠大于BDP時,會頻繁引發網絡擁塞,造成逾時,也就是著名的TCP吞吐率崩塌問題,也稱為Incast問題。

說這麼多,意義何在呢?啟發TCP下一步的改進方向,基于視窗的擁塞控制能力有限,或許已經到了改變的時候了【注 2】。TCP下一步的改變方向或許是“速率控制”,而非“視窗控制”。丢包時,“速率減半”。RCP等協定是基于速率的。表面看來,這兩種控制方式并無差别。但是速率控制能精确控制發送速率,而不降低負載率。舉例來說,如果視窗到了1MSS,還是不能避免丢包擁塞逾時,那怎麼辦呢?很多人會說減小MSS,可是這會降低帶寬使用率,舉例來說,當MSS為500時,帶寬使用率最大為40/540,因為標頭的40位元組是無用的。比40/1500低了很多。而速率控制方法可以在不降低帶寬使用率的情況下控制發送速率。其根本差別在于:基于視窗的控制政策是burst投遞,也就是突發投遞【注 3】。而基于速率的控制可以漸緩投遞。

講到這裡,是否有醍醐灌頂的感覺?傳輸控制的本質已經在你眼前揭開了,希望你得到點什麼,不過那并不是屬于你自己的東西,而是無數前輩的結晶,我隻是按我的了解方式叙述而已。

3.QUIC的機制

QUIC具有的特性如下【引 4】:

-RTT connections
Packet pacing that reduces packet loss
Forward error correction that reduces retransmission latency
Adaptive congestion control (friendly to TCP), reducing reconnections for mobile clients
Encryption equivalent to TLS
Chrome can talk QUIC to Google today       

其中,QUIC對packet loss和擁塞避免的處理最值得關注。下面我來介紹這兩部分處理【引 5】。

packet loss:QUIC丢包恢複有兩種辦法,前向糾錯(FEC)和重傳。前向糾錯可以減少重傳,但需要在包中添加備援資訊,用XOR實作【注 4】。如果前向糾錯不能恢複包,就啟用重傳,重傳的不是舊包,而是重新構造的包。

congestion avoidance:TCP使用了視窗來進行擁塞控制,QUIC使用帶寬探測器、監察delay變化并使用pacing來減少丢包【注 5】。當接收端判定丢包後,發送NACK給對端,通知丢包事件。此後進行的速率降低工作類似于TCP,保持對TCP的友好性。

(本篇隻是開頭,QUIC的源碼我還沒把握體系,關于QUIC的内容會逐漸補充,待續。。。)

引用

【1】QUIC FAQ for Geeks。

https://docs.google.com/document/d/1lmL9EF6qKrk7gbazY8bIdvq3Pno2Xj_l_YShP40GLQE/edit。參見“Why isn’t SPDY over TCP good enough?”。

【2】Head-of-line blocking。http://en.wikipedia.org/wiki/Head-of-line_blocking。

【3】HTTP pipeline。http://en.wikipedia.org/wiki/HTTP_pipelining。HTTP pipeling特性支援把多條HTTP連接配接封裝到一條TCP連接配接中,但Head-of-line blocking會嚴重降低這種複用連接配接的性能。這本來是為了減少握手互動時間而提出的特性改進,卻帶來了上述的性能降低問題。

【4】QUIC特性。http://www.infoq.com/news/2014/02/quic。

【5】QUIC dealing with packet loss。https://docs.google.com/document/d/1RNHkx_VvKWyWg6Lr8SZ-saqsQx7rFV-ev2jRFUoVD34/edit#。

注解

【1】将擁塞控制分離的想法很早就有人提出,基于傳輸層的可靠協定UDT或TCP甚至也可以分離到核心之外,成為使用者空間協定棧。

【2】If you understand these words, congratulations! This thought is very meaningful, in other words, it may be epochal. You deserve it. But don't say the thought owe to you, because it's not my own, it's proposed by researchers. Thanks to my friend, "jedihy" (http://c2fun.cn 8th blogs of him), I got the idea from him.

【3】參閱TCP Pacing。

【4】前向糾錯并不是一種新手段,基于XOR的包恢複政策屢見不鮮,參閱“鍊路層 network coding”。

【5】pacing是一個重要政策,如果你了解了第一部分“TCP的症結”,就會知道它有多重要。