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


前面我們演示分析了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和一些其他的擁塞控制算法。

1、TFRC

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。

2、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擁塞控制也就不能充分利用高速網絡了。

3、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在擁塞避免過程中的慢啟動過程。


4、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等,感興趣的可以一讀。

5、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的論文並沒有復雜的數學推算,是相對容易理解的一篇。

6、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+能高效的處理非擁塞丟包和擁塞丟包。

7、其他擁塞控制算法

上面着重介紹了幾個比較典型的擁塞控制算法,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等等。


補充說明:

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

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

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

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

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

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

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

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

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

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

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

















免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM