TCP性能:
以下摘自:https://www.cnblogs.com/cnhk19/p/9413548.html
作者:henrystark henrystark@126.com
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】:
0-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的症結”,就會知道它有多重要。
待續...