cubic演算法優化 TCP 擁塞控制演算法

2021-10-14 14:45:15 字數 3280 閱讀 4166

最近花了些時間在學習tcp/ip協議上,首要原因是由於本人長期以來對tcp/ip的認識就只限於三次握手四次分手上,所以希望深入了解一下。再者,tcp/ip和linux系統層級的很多設計都可以用於中介軟體系統架構上,比如說tcp 擁塞控制演算法也可以用於以響應時間來限流的中介軟體。更深一層,像tcp/ip協議這種基礎知識和原理性的技術,都是經過長時間的考驗的,都是前人智慧型的結晶,可以給大家很多啟示和幫助。

本文中會出現一些縮寫,因為篇幅問題,無法每個都進行解釋,如果你不明白它的含義,請自己去搜尋了解,做乙個主動尋求知識的人。

tcp協議有兩個比較重要的控制演算法,乙個是流量控制,另乙個就是阻塞控制。

tcp協議通過滑動視窗來進行流量控制,它是控制傳送方的傳送速度從而使接受者來得及接收並處理。而擁塞控制是作用於網路,它是防止過多的包被傳送到網路中,避免出現網路負載過大,網路擁塞的情況。

擁塞演算法需要掌握其狀態機和四種演算法。擁塞控制狀態機的狀態有五種,分別是open,disorder,cwr,recovery和loss狀態。四個演算法為慢啟動,擁塞避免,擁塞發生時演算法和快速恢復。

和tcp一樣,擁塞控制演算法也有其狀態機。當傳送方收到乙個ack時,linux tcp通過狀態機(state)來決定其接下來的行為,是應該降低擁塞視窗cwnd大小,或者保持cwnd不變,還是繼續增加cwnd。如果處理不當,可能會導致丟包或者超時。

open狀態是擁塞控制狀態機的預設狀態。這種狀態下,當ack到達時,傳送方根據擁塞視窗cwnd(congestion window)是小於還是大於慢啟動閾值ssthresh(slow start threshold),來按照慢啟動或者擁塞避免演算法來調整擁塞視窗。

當傳送方檢測到dack(重複確認)或者sack(選擇性確認)時,狀態機將轉變為disorder狀態。在此狀態下,傳送方遵循飛行(in-flight)包守恆原則,即乙個新包只有在乙個老包離開網路後才傳送,也就是傳送方收到老包的ack後,才會再傳送乙個新包。

傳送方接收到乙個擁塞通知時,並不會立刻減少擁塞視窗cwnd,而是每收到兩個ack就減少乙個段,直到視窗的大小減半為止。當cwnd正在減小並且網路中有沒有重傳包時,這個狀態就叫cwr(congestion window reduced,擁塞視窗減少)狀態。cwr狀態可以轉變成recovery或者loss狀態。

當傳送方接收到足夠(推薦為三個)的dack(重複確認)後,進入該狀態。在該狀態下,擁塞視窗cnwd每收到兩個ack就減少乙個段(segment),直到cwnd等於慢啟動閾值ssthresh,也就是剛進入recover狀態時cwnd的一半大小。 傳送方保持 recovery 狀態直到所有進入 recovery狀態時正在傳送的資料段都成功地被確認,然後傳送方恢復成open狀態,重傳超時有可能中斷 recovery 狀態,進入loss狀態。

當乙個rto(重傳超時時間)到期後,傳送方進入loss狀態。所有正在傳送的資料標記為丟失,擁塞視窗cwnd設定為乙個段(segment),傳送方再次以慢啟動演算法增大擁塞視窗cwnd。

loss 和 recovery 狀態的區別是:loss狀態下,擁塞視窗在傳送方設定為乙個段後增大,而 recovery 狀態下,擁塞視窗只能被減小。loss 狀態不能被其他的狀態中斷,因此,傳送方只有在所有 loss 開始時正在傳輸的資料都得到成功確認後,才能退到 open 狀態。

擁塞控制主要是四個演算法:1)慢啟動,2)擁塞避免,3)擁塞發生,4)快速恢復。這四個演算法不是一天都搞出來的,這個四演算法的發展經歷了很多時間,到今天都還在優化中。

所謂慢啟動,也就是tcp連線剛建立,一點一點地提速,試探一下網路的承受能力,以免直接擾亂了網路通道的秩序。

慢啟動演算法:

1) 連線建好的開始先初始化擁塞視窗cwnd大小為1,表明可以傳乙個mss大小的資料。 2) 每當收到乙個ack,cwnd大小加一,呈線性上公升。 3) 每當過了乙個往返延遲時間rtt(round-trip time),cwnd大小直接翻倍,乘以2,呈指數讓公升。 4) 還有乙個ssthresh(slow start threshold),是乙個上限,當cwnd >= ssthresh時,就會進入「擁塞避免演算法」(後面會說這個演算法)

如同前邊說的,當擁塞視窗大小cwnd大於等於慢啟動閾值ssthresh後,就進入擁塞避免演算法。演算法如下:

1) 收到乙個ack,則cwnd = cwnd + 1 / cwnd 2) 每當過了乙個往返延遲時間rtt,cwnd大小加一。

過了慢啟動閾值後,擁塞避免演算法可以避免視窗增長過快導致視窗擁塞,而是緩慢的增加調整到網路的最佳值。

一般來說,tcp擁塞控制預設認為網路丟包是由於網路擁塞導致的,所以一般的tcp擁塞控制演算法以丟包為網路進入擁塞狀態的訊號。對於丟包有兩種判定方式,一種是超時重傳rto[retransmission timeout]超時,另乙個是收到三個重複確認ack。

超時重傳是tcp協議保證資料可靠性的乙個重要機制,其原理是在傳送乙個資料以後就開啟乙個計時器,在一定時間內如果沒有得到傳送資料報的ack報文,那麼就重新傳送資料,直到傳送成功為止。

但是如果傳送端接收到3個以上的重複ack,tcp就意識到資料發生丟失,需要重傳。這個機制不需要等到重傳定時器超時,所以叫 做快速重傳,而快速重傳後沒有使用慢啟動演算法,而是擁塞避免演算法,所以這又叫做快速恢復演算法。

超時重傳rto[retransmission timeout]超時,tcp會重傳資料報。tcp認為這種情況比較糟糕,反應也比較強烈:

最為早期的tcp tahoe演算法就只使用上述處理辦法,但是由於一丟包就一切重來,導致cwnd又重置為1,十分不利於網路資料的穩定傳遞。

所以,tcp reno演算法進行了優化。當收到三個重複確認ack時,tcp開啟快速重傳fast retransmit演算法,而不用等到rto超時再進行重傳:

tcp tahoe是早期的演算法,所以沒有快速恢復演算法,而reno演算法有。在進入快速恢復之前,cwnd和ssthresh已經被更改為原有cwnd的一半。快速恢復演算法的邏輯如下:

如圖所示,第五個包發生了丟失,所以導致接收方接收到三次重複ack,也就是ack5。所以將ssthresh設定當當時cwnd的一半,也就是6/2 = 3,cwnd設定為3 + 3 = 6。然後重傳第五個包。當收到新的ack時,也就是ack11,則退出快速恢復階段,將cwnd重新設定為當前的ssthresh,也就是3,然後進入擁塞避免演算法階段。

TCP的擁塞避免演算法

23.客戶端c和伺服器s之間建立乙個tcp連線,該連線總是以1kb的最大段長傳送tcp段 客戶端c有足夠的資料要傳送。當擁塞視窗為16kb的時候發生超時 如果接下來的4個rtt往返時間內的tcp段的傳輸是成功的,那麼當第4個rtt時間內傳送的所有tcp段都得到了ack時,擁塞視窗大小是 16kb超時...

TCP協議 擁塞控制演算法

網路擁塞控制演算法 tcp的擁塞控制主要原理依賴於乙個擁塞視窗來控制,在之前我們還討論過tcp還有乙個對端通告的接收視窗用於流量控制。視窗值得大小就代表能夠傳送出去的但還沒有接收到ack的最大資料報文段,顯然視窗越大那麼資料傳送的速度也就越快,但是也有越可能使得網路出現擁塞,如果視窗值為1,那麼就簡...

tcp擁塞控制演算法 WebRTC擁塞控制原理解析

webrtc包含三種擁塞控制演算法,gcc bbr和pcc。其中,bbr一開始是針對tcp的擁塞控制提出來的。它的輸入為ack sack,輸出為擁塞視窗 congestion window 傳送速度 pacing rate bbr是怎樣運用到udp,甚至運用到實時流 傳輸之上的?拜讀一下在webrt...