TCP系列55—擁塞控制—1八、其餘擁塞控制算法及相關內容概述

前面咱們演示分析了100+個wireshark TCP實例,擁塞控制部分也介紹常見的擁塞處理場景以及4種擁塞撤銷機制,可是咱們一直使用的都是reno擁塞控制算法。實際上擁塞控制發展到今天已經有了各類各樣的擁塞控制算法,並且廣泛認爲單純基於丟包的reno擁塞控制算法已經不適應當前internet網絡了,最近谷歌又折騰出了一個BBR擁塞控制算法,對比國內,尚未一個在TCP領域有突出貢獻的公司,谷歌在TCP領域真是甩了其餘公司好幾條街。閒言少敘吧,擁塞控制關注的Scalability、RTT fairness、TCP friendliness、 convergence等等須要複雜的數學推理,響應函數(response function) 則是擁塞控制的一個重要特性,從響應函數的斜率、與AIMD(1,0.5)的交匯等能夠大體觀察出RTT fairness、TCP friendliness、Scalability等特色。好在多數時候咱們即便不理解太深奧的數學推理也能夠從直觀上理解一個擁塞控制算法的處理思路和原理。下面簡單介紹一下TFRC和一些其餘的擁塞控制算法。html

一、TFRClinux

TFRC(TCP Friendly Rate Control)是Internet環境中單播數據流的一個擁塞控制機制。總體的發送速率上,TFRC能夠相對公平的與TCP競爭網絡帶寬,可是相比TCP,其吞吐量在時間上更爲平穩,所以TFRC更適合須要平穩速率的流媒體應用。注意TFRC是一個擁塞控制機制,它能夠應用在傳輸層中,如DCCP,也可使用在應用層中作擁塞控制。算法

TFRC要保證與TCP公平競爭的同時還要保證傳輸速率的平穩,帶來的後果就是TFRC對網絡可用帶寬的變化的響應比TCP的響應更慢。所以RFC5348指出只有確實須要平滑傳輸速率的應用才應該使用TFRC。而應用層若是隻是簡單的想要在儘量短的時間內傳輸儘量多的數據,那麼仍是建議使用TCP,或者與TCP相似的AIMD擁塞控制機制。緩存

TFRC是設計用來控制發送數據包大小基本不變業務,TFRC經過改變每秒發送的數據包的個數來響應擁塞。它是一個接收端的機制,可是也能夠在發送端來實現。網絡

TFRC基本原理:Padhye在1998年給出了TCP速率估計公式,推導除了TCP發送速率與RTT和丟包率的關係。RFC5348中的TFRC則是根據這個公式,經過探測網絡的丟包率和RTT來限制發送端的速率。這樣總體速率上就能夠保證與TCP相對公平競爭,另一方面在保證總體速率符合該公式限制的前提下,TFRC在發生擁塞時,下降發送速率不會如TCP那麼猛烈。例如TFRC在RTO(RTO爲4*RTT)超時時,只會把容許的發送速率下降爲一半,而TCP會把cwnd直接下降爲1。tcp

二、HSTCP函數

以前演示的一直是reno擁塞控制算法,咱們能夠粗略估計一下reno在高速TCP環境下的處理,在一個RTT爲100ms,帶寬爲10Gbps,包大小爲1500bytes的網絡中,若是要滿速率發送cwnd>=10*1000*1000*1000*100/1000/8/1500=83333。假設cwnd=83333,若是發生快速重傳cwnd減半後從新進行擁塞避免過程,擁塞避免過程當中每個RTT,cwnd增1,那麼大約須要83333/2*100=4166666ms=4166s=69min,經過簡單計算咱們能夠發現,這種場景下大約須要69分鐘,reno的擁塞避免過程才能讓cwnd足夠大以充分利用10Gbps的帶寬,顯然69分鐘的擁塞避免過程時間太長了,並且極可能會形成帶寬浪費。實際上受限於丟包率,reno的一個典型問題就是還沒等cwnd增加到足夠利用10Gbps的值就已經發生丟包並削減cwnd了。性能

而RFC3649中的HSTCP(HighSpeed TCP)就是根據這種場景進行的優化改進,HSTCP的慢啓動過程與咱們以前介紹的reno算法的慢啓動過程一致,可是HSTCP會改變AIMD行爲。咱們把標準TCP的AIMD過程泛化爲下面的公式學習

cwnd=cwnd+a(w)/cwnd優化

cwnd=cwnd-b(w)*cwnd

在標準TCP中a(w)=1,b(w)=0.5,而在HSTCP中a(w)和b(w)則是一個隨着cwnd的大小而變化的值,根據linux代碼中的相關參數繪製了以下的關係曲線,其中a(w)/cwnd就表示每收到一個數據包的ACK,cwnd_cnt這個狀態變量自增多少,在cwnd<=38的時候,a(w)=1,b(w)=0.5,所以對於低速TCP,HSTCP算法與標準TCP算法是一致的,可是對於高速TCP,a(w)變大,b(w)變小,這樣當發生快速重傳的時候cwnd的削減就不會如標準TCP那麼猛烈,並且收到ACK報文的時候,cwnd_cnt的增加也更爲迅速。

實際上HSTCP是把標準TCP的響應函數(response function)由w = 1.2/sqrt(p)近似改成了w= 0.12/p^0.835,其中w表示每一個RTT容許發送的報文的個數,p表示丟包率。對這個感興趣的能夠參考RFC3649或者其餘相關資料。HSTCP的實現代碼其實也只有一百多行了,感興趣的自行參考。

咱們再粗略估計一下以前的那個例子使用HSTCP的時候,須要多長時間來恢復,在linux代碼實現中當75401<cwnd<=79517時候,a(w)=70, b(w)=0.1016, 當75401<cwnd<=79517時a(w)=71,b(w)=0.0977,所以對於上面舉的10Gbps的例子,當cwnd=83333,發生快速重傳而且快速恢復後,更新cwnd=cwnd-0.0977*cwnd=75171,恢復所須要的總時間爲,((79517-75171)/70+(83333-79517)/71)*RTT=12s。經過對比能夠看到快速重傳/快速恢復後經過擁塞避免恢復到相同水平,reno須要約69分鐘,而HSTCP只須要大約12s。並且在實際的reno的69分鐘恢復過程當中,極可能已經發生了比特錯誤(比特錯誤雖然是一個機率很低的事件,可是在高速網絡中69分鐘內能夠傳輸大量的數據包,於是這期間發生比特錯誤的機率是很是高的,能夠參考BICTCP的論文)從而致使再次觸發快速重傳,cwnd所以很難達到理論最高水平,reno擁塞控制也就不能充分利用高速網絡了。

三、BIC(Binary Increase Congestion Control)

BICTCP一樣是針對LFN(long fat networks)網絡的,BICTCP最開始叫作BITCP。值得一提的是BICTCP和下面要介紹的CUBIC的主要做者中有一個是北京科技大學畢業的,後在NCSU期間與人合做設計了這兩個擁塞控制算法。在2004年BITCP的論文中,做者們研究發現當時已有的針對高速網絡的TCP擁塞控制算法HSTCP和STCP有嚴重的RTT不公平性,這種RTT的不公平性在沒有AQM機制的路由器中尤其嚴重。BITCP(Binary  Increase  TCP)分爲兩部分,一部分叫作binary search increase,另一部分叫作additive increase。在快速重傳/快速恢復後,BITCP會以二分查找來更新cwnd以找到最合適的窗口大小(做者稱呼爲saturation point),舉個例子假如,cwnd=100的時候觸發了一次快速重傳/快速恢復過程,假設BITCP的參數β=0.2,則cwnd更新爲 cwnd=cwnd*(1-0.2)=80,接着收到ACK的時候會把cwnd更新爲cwnd+=((100+80)/2-80)/cwnd,即一個RTT內cwnd自增10,接着下一個RTT內cwnd自增5,以此類推,這個過程就叫作binary search increase。至於additive increase過程是爲了防止上面binary search increase過程當中cwnd自增過快,所以會有一個最大自增參數,限制cwnd每一個RTT的自增值不超過最大自增參數。

BICTCP還有一個快速收斂過程和慢啓動過程,注意這個慢啓動過程並非咱們以前介紹的慢啓動過程,BITCP的的慢啓動是在擁塞避免的過程內的一個慢啓動。另外一樣爲了保證TCP friendliness,在cwnd很小的時候,依然按照標準TCP的AIMD過程更新cwnd,並不會啓動BICTCP。快速收斂和BITCP的慢啓動過程等內容請參考做者的論文吧,這裏再也不進行詳細介紹。可先閱讀做者原始論文中的僞代碼,而後就容易理解linux的實現代碼了。

最後給出BICTCP的cwnd增加圖示,其中右側的Max Probing就是BICTCP在擁塞避免過程當中的慢啓動過程。


四、CUBIC

目前CUBIC是linux內核的默認擁塞控制算法。BICTCP的做者認爲BICTCP有兩個不足,一個是BICTCP的擁塞避免劃分爲三個階段:additive increase、binary search increase和slow start,增長了複雜性。另外在低速網絡或者網絡RTT比較小的時候,BICTCP的增加函數對於TCP來講太激進。所以做者使用了一個立方函數(cubic function)來做爲cwnd的增加函數,這種改進後的擁塞控制算法就稱爲cubic算法。

CUBIC中使用的立方函數以下

其中Wcubic表示在時間T時刻,容許發發送窗口大小,Wmax表示在發生快速重傳前的cwnd,C是一個常量參數(默認爲0.4),β是乘法減少常量因子(默認爲0.2)。CUBIC的增加曲線以下,能夠看到CUBIC的增加與BICTCP的增加趨勢很是相似。相比BICTCP,CUBIC在Wmax附近的增加更爲平緩。CUBIC的詳細內容能夠參考<CUBIC: A New TCP-Friendly High-Speed TCP Variant>,本篇僅做概述再也不深刻。


另外NCSU那幫人後來又提出了一個HyStart(Hybrid Start)的慢啓動算法,傳統的慢啓動算法每一個RTT時間cwnd翻一倍,當cwnd接近BDP的時候, 容易形成大量丟包,在不支持AQM的路由器上還會形成同步丟包,下降了TCP的性能。HyStart可使用ACK train或者Delay increase機制來提早終止慢啓動並進入擁塞避免。目前在linux中的CUBIC算法默認是使能HyStart慢啓動算法的。另外在HyStart的原始論文中還介紹了其餘的幾種慢啓動算法LSS、Astart、Vstart等,感興趣的能夠一讀。

五、Vegas

Vegas是第一個基於時延的比較系統完整的擁塞控制算法,後續不少基於時延的擁塞控制都借鑑了Vegas的思想,其實在Vegas以前也有一些基於時延改善擁塞控制的算法。咱們在擁塞控制概述的時候,給出了一張網絡負載與響應時間的關係圖吧。當網絡負載逐漸加大,網絡擁塞的時候,數據包就會在中間設備上緩存等待處理,進而使得網絡的RTT變大,所以咱們可使用網絡的時延來估計網絡的擁塞狀況。在1995年的Vegas論文中提出了三種技術來提高TCP的吞吐量下降丟包。第一個是Vegas能夠採用一個更早期的決定來重傳丟失的數據包。第二個是Vegas在擁塞避免階段,TCP經過估計網絡的擁塞程度,進而調整TCP的發送速率。第三個是修改了TCP的慢啓動機制,在初始慢啓動階段能夠在避免丟包的狀況下找到合適大小的可用帶寬,這就是咱們上面提到的Vstart慢啓動方法。

Vegas的重點是上面描述的三個技術中的第二個,即擁塞窗口調整。其基本思想是:當擁塞窗口增大的時候,預期發送速率也會同步增大,可是這個發送速率不能超過可用帶寬,當發送速率到達可用帶寬的時候,再次增大擁塞窗口,發送速率不會再次增大,額外發出的數據包(做者在論文中稱呼這種數據爲extra data)只會在產生瓶頸的路由器中積累。Vegas的目標就是維護合適的extra data數據量。若是一個TCP鏈接發送太多的extra data,那麼就會產生擁塞最終丟包,若是extra data太少,那麼當可用帶寬變大的時候,對應的鏈接可能就不能快速的響應。按照做者描述,Vegas會計算一個實際發送速率Actual和一個預期的速率Expected,其中Expected=cwnd/BaseRTT,BaseRTT是測量到的最小的RTT,而Actual則是根據當前鏈接採樣的RTT和cwnd計算得來。接着計算Diff=Expected-Actual,Vegas會維護兩個門限參數α和β(α<β),當Diff<α的時候,Vegas線性的增大cwnd,當Diff>β時候,Vegas線性的減少擁塞窗口,當α<Diff<β的時候,Vegas維持cwnd不變。

Vegas在擁塞避免階段採用的是AIAD的方式來更新cwnd。Vegas的性能其實是比reno要好的,可是由於Vegas通常是在發生丟包前起做用,而reno則是一直增大發送速率直到丟包,所以在帶寬的爭奪上Vegas競爭不過reno,從而限制了Vegas的應用。對詳細內容感興趣的建議閱讀一下做者的原始論文,這篇論文相比BIC、HSTCP的論文並無複雜的數學推算,是相對容易理解的一篇。

六、Westwood和Westwood+

Westwood TCP(簡稱爲TCPW)能夠當作是reno和Vagae的結合,TCPW在Lossy-Link網絡環境下有很是優異的表現。Loss-Link是指具備很是高的非擁塞丟包比例的網絡環境,例如Wifi網絡。Westwood+ TCP(簡稱爲TCPW+)則使用更長的帶寬估計間隔和優化的濾波器修復了TCPW在ACK compression(以前咱們介紹過,ACK compression指接收端間隔發送的ACK確認包一塊兒到達發送端)場景下對帶寬估計太高的問題。Linux中實現的是TCPW+,咱們這裏直接概述一下TCPW+的處理。

TCPW+使用端到端的帶寬估計來處理非擁塞丟包)。相似Vegas,TCPW+在每一個RTT都會就算一個估計一個帶寬值BW=D/RTT,其中D表示在這個RTT裏面成功傳輸到接收端的數據量,接着對BW進行濾波後獲得帶寬的估計值BWE,另外在TCPW+還會維護更新一個RTT的最小值min_RTT,當發生超時重傳時,更新cwnd=1,ssthresh=max(2,(BWE*min_RTT)),在快速重傳/快速恢復後,更新cwnd=ssthresh=max(2,(BWE*min_RTT))。

當發生非擁塞丟的時候,RTT通常不會有劇烈變化,所以BWE能有有效的估計可用帶寬。而發生擁塞丟包的時候,RTT顯著上升,BWE則會顯著變小一樣能夠估計可用帶寬。所以TCPW+能高效的處理非擁塞丟包和擁塞丟包。

七、其餘擁塞控制算法

上面着重介紹了幾個比較典型的擁塞控制算法,HSTCP是針對高速網絡的擁塞控制,Vegas是基於時延的擁塞控制,而TCPW+是綜合利用時延和丟包進行的擁塞控制,CUBIC是當前Linux內核的默認擁塞控制算法。理解這些典型的擁塞控制算法(代碼+論文/協議)對於學習其餘的擁塞控制算法會有很大幫助。下面簡單概述一下其餘的擁塞控制算法

FAST TCP:FAST TCP是一個與Vegas緊密關聯的擁塞控制算法,並且做者已經在USPTO申請了專利。FAST TCP一樣是針對高BDP網絡的,當測量到的RTT接近最小RTT的時候,說明網絡並無發生擁塞,FAST TCP相比Vegas會更激進的調整cwnd,從而能夠與reno競爭帶寬。

Veno TCP:Veno一樣是一個Vegas與Reno的綜合體,Veno嘗試解決的是lossy-link網絡的擁塞控制,而不是高帶寬網絡的擁塞控制。和Vegas相似,Veno經過Nqueue = cwnd - BWE×min_RTT來估計隊列緩存,在擁塞避免階段會根據Nqueue來更新cwnd,當發送速率接近鏈路飽和點的時候,cwnd更新就會變緩。另外當發生丟包的時候,Veno會根據Nqueue來判斷當前丟失是擁塞丟包仍是非擁塞丟包,並對ssthresh作不一樣的處理。

Hybla TCP:針對高時延網絡的擁塞控制,典型的如衛星網絡。標準的Reno混合組網下,RTT較大的鏈接的速率將會遠小於正常RTT的鏈接。Hybla則是針對這種場景作的優化,Hybla會選定一個RTT0做爲參考RTT,RTT0默認爲25ms,它會使得其餘RTT的TCP鏈接在擁塞控制方面等效於RTT0的Reno的TCP鏈接。

另外還有不少擁塞控制算法我也沒有了解,例如前面ECN介紹文章中提到的DCTCP、利用剩餘帶寬的LP TCP、高速網絡中的HTCP、YeAH TCP、還有最新的BBR等等。


補充說明:

一、注意第二版TCP/IP Illustrated Vol1 P769給出的速率公式分母有問題,公式過於複雜這裏再也不給出,詳細請查詢RFC5348或者我總結的部分勘誤

二、https://en.wikipedia.org/wiki/TCP_Friendly_Rate_Control

三、TFRC速率公式 http://conferences.sigcomm.org/sigcomm/1998/tp/paper25.pdf

四、TFRC https://tools.ietf.org/html/rfc5348

五、HSTCP http://www.icir.org/floyd/papers/hstcp.pdf  https://tools.ietf.org/html/rfc3649

六、BIC TCP http://netsrv.csc.ncsu.edu/export/bitcp.pdf

七、CUBIC http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf   

八、BIC與CUBIC https://research.csc.ncsu.edu/netsrv/?q=content/bic-and-cubic

九、HyStart http://netsrv.csc.ncsu.edu/export/hystart_techreport_2008.pdf  https://research.csc.ncsu.edu/netsrv/sites/default/files/hybridstart_pfldnet08.pdf

十、Vegas http://www.cs.toronto.edu/syslab/courses/csc2209/06au/papers/vegas.pdf

十一、TCPW/TCPW+ http://www.signal.uu.se/Research/PCCWIP/Mobicom01Mascolo.pdf   http://c3lab.poliba.it/images/f/f7/Ccr_v31.pdf














相關文章
相關標籤/搜索