TCP——擁塞控制
注意,注意,注意:
1、這是我2018找實習、找工作的總結,是在網上結合很多別人總結文章自己再東拼西湊的,如有錯誤請大家指出,我再去找資料補充。
2、很多內容來自別人博主,十分感謝,當時摘抄實在太匆忙,有的忘了出處,如有冒犯,侵刪。
3、祝各位很閒也有錢。
一般原理
發生擁塞控制的原因:資源(頻寬、交換節點的快取、處理機)的需求>可用資源。
作用:擁塞控制就是為了防止過多的資料注入到網路中,這樣可以使網路中的路由器或者鏈路不至於過載。擁塞控制要做的都有一個前提:就是網路能夠承受現有的網路負荷。 對比流量控制:擁塞控制是一個全域性的過程,涉及到所有的主機、路由器、以及降低網路相關的所有因素。流量控制往往指點對點通訊量的控制。是端對端的問題。
擁塞視窗:傳送方為一個動態變化的視窗叫做擁塞視窗,擁塞視窗的大小取決於網路的擁塞程度。傳送方讓自己的傳送視窗=擁塞視窗,但是傳送視窗不是一直等於擁塞視窗的,在網路情況好的時候,擁塞視窗不斷的增加,傳送方的視窗自然也隨著增加,但是接受方的接受能力有限,在傳送方的視窗達到某個大小時就不在發生變化了。傳送方維持一個叫做擁塞視窗CWND(congestion window)的狀態變數。傳送方的擁塞視窗等於自己傳送視窗。
擁塞控制演算法:
- 慢啟動+擁塞避免
- 慢啟動+快重傳+快恢復
一、慢啟動+擁塞避免
慢啟動演算法的思路:主機開發傳送資料報時,如果立即將大量的資料注入到網路中,可能會出現網路的擁塞。慢啟動演算法就是在主機剛開始傳送資料報的時候先探測一下網路的狀況,如果網路狀況良好,傳送方每傳送一次文段都能正確的接受確認報文段。那麼就從小到大的增加擁塞視窗的大小,即增加發送視窗的大小。
例項:開始傳送方先設定cwnd(擁塞視窗)=1,傳送第一個報文段M1,接收方接收到M1後,傳送方接收到接收方的確認後,把cwnd增加到2,接著傳送方傳送M2、M3,傳送方接收到接收方傳送的確認後cwnd增加到4,慢啟動演算法每經過一個傳輸輪次(認為傳送方都成功接收接收方的確認),擁塞視窗cwnd就加倍。
擁塞避免:為了防止cwnd增加過快而導致網路擁塞,所以需要設定一個慢開始門限ssthresh狀態變數(我也不知道這個到底是什麼,就認為他是一個擁塞控制的標識),它的用法: - 當cwnd < ssthresh,使用慢啟動演算法, - 當cwnd > ssthresh,使用擁塞控制演算法,停用慢啟動演算法。 - 當cwnd = ssthresh,這兩個演算法都可以。
擁塞避免的思路:是讓cwnd緩慢的增加而不是加倍的增長,每經歷過一次往返時間就使cwnd增加1,而不是加倍,這樣使cwnd緩慢的增長,比慢啟動要慢的多。
無論是慢啟動演算法還是擁塞避免演算法,只要判斷網路出現擁塞,就要把慢啟動開始門限(ssthresh)設定為設定為傳送視窗的一半(>=2),cwnd(擁塞視窗)設定為1,然後在使用慢啟動演算法,這樣做的目的能迅速的減少主機向網路中傳輸資料,使發生擁塞的路由器能夠把佇列中堆積的分組處理完畢。擁塞視窗是按照線性的規律增長,比慢啟動演算法擁塞視窗增長塊的多。
例項: 1.TCP連線進行初始化的時候,cwnd=1,ssthresh=16。 2.在慢啟動演算法開始時,cwnd的初始值是1,每次傳送方收到一個ACK擁塞視窗就增加1,當ssthresh =cwnd時,就啟動擁塞控制演算法,擁塞視窗按照規律增長, 3.當cwnd=24時,網路出現超時,傳送方收不到確認ACK,此時設定ssthresh=12,(二分之一cwnd),設定cwnd=1,然後開始慢啟動演算法,當cwnd=ssthresh=12,慢啟動演算法變為擁塞控制演算法,cwnd按照線性的速度進行增長。
如何檢測擁塞? 首先來看TCP是如何確定網路進入了擁塞狀態的,TCP認為網路擁塞的主要依據是它重傳了一個報文段。上面提到過,TCP對每一個報文段都有一個定時器,稱為重傳定時器(RTO),當RTO超時且還沒有得到資料確認,那麼TCP就會對該報文段進行重傳,當發生超時時,那麼出現擁塞的可能性就很大,某個報文段可能在網路中某處丟失,並且後續的報文段也沒有了訊息,在這種情況下,TCP反應比較“強烈”: 1.把ssthresh降低為cwnd值的一半 2.把cwnd重新設定為1 3.重新進入慢啟動過程。 從整體上來講,TCP擁塞控制視窗變化的原則是AIMD原則,即加法增大、乘法減小。可以看出TCP的該原則可以較好地保證流之間的公平性,因為一旦出現丟包,那麼立即減半退避,可以給其他新建的流留有足夠的空間,從而保證整個的公平性。
AIMD(加法增大乘法減小) 1. 乘法減小:無論在慢啟動階段還是在擁塞控制階段,只要網路出現超時,就是將cwnd置為1,ssthresh置為cwnd的一半,然後開始執行慢啟動演算法(cwnd<ssthresh)。 2. 加法增大:當網路頻發出現超時情況時,ssthresh就下降的很快,為了減少注入到網路中的分組數,而加法增大是指執行擁塞避免演算法後,是擁塞視窗緩慢的增大,以防止網路過早出現擁塞。 這兩個結合起來就是AIMD演算法,是使用最廣泛的演算法。擁塞避免演算法不能夠完全的避免網路擁塞,通過控制擁塞視窗的大小隻能使網路不易出現擁塞。
二、慢啟動+快重傳+快恢復
快重傳(Fast Retransmit) 1、要求接收方每收到一個失序的報文段後就立即發出重複確認而不是等待自己傳送資料時才捎帶確認 2、傳送方只要一連收到三個重複確認就立即重傳對方尚未收到的報文段,而不必等待設定的重傳計時器到期
有的快重傳實現把開始時的擁塞視窗cwnd設定為ssthresh+3*MSS的位元組數值,原因是認為收到三個重複確認後,表明網路中已經有三個分組離開了,證明現在網路中並沒有堆積分組,因此適當增大擁塞視窗
快恢復(Fast Recovery)
當傳送方連續收到三個重複確認時,就執行“乘法減小”演算法,把慢開始門限ssthresh減半,為了預防網路擁塞 將擁塞視窗cwnd值設定為慢開始門限ssthresh減半後的數值,然後開始執行擁塞避免演算法 TCP Tahoe版本與TCP Reno版本的區別:Reno版本在快重傳之後採用快恢復演算法而不是採用慢開始演算法
總結
1、採用快恢復演算法時,慢開始演算法只是在TCP建立連線和網路出現超時時才使用 2、接收方根據自己的接收能力設定了接收視窗rwnd,將此視窗值寫入TCP首部傳送給對方。結合擁塞控制,傳送方的傳送視窗一定不能大於接收方給出的接收視窗且一定不能大於自己的擁塞視窗 3、傳送方的傳送視窗的上限值 = Min[rwnd, cwnd]
補充:隨機早期檢測RED
以上的擁塞避免演算法並沒有和網路層聯絡起來,實際上網路層的策略對擁塞避免演算法影響最大的就是路由器的丟棄策略。在簡單的情況下路由器通常按照先進先出的策略處理到來的分組。當路由器的快取裝不下分組的時候就丟棄到來的分組,這叫做尾部丟棄策略。這樣就會導致分組丟失,傳送方認為網路產生擁塞。更為嚴重的是網路中存在很多的TCP連線,這些連線中的報文段通常是複用路由路徑。若發生路由器的尾部丟棄,可能影響到很多條TCP連線,結果就是這許多的TCP連線在同一時間進入慢開始狀態。這在術語中稱為全域性同步。全域性同步會使得網路的通訊量突然下降很多,而在網路恢復正常之後,其通訊量又突然增大很多。 為避免發生網路中的全域性同步現象,路由器採用隨機早期檢測(RED:randomearly detection)。該演算法要點如下: 使路由器的佇列維持兩個引數,即佇列長隊最小門限min和最大門限max,每當一個分組到達的時候,RED就計算平均佇列長度。然後分情況對待到來的分組: ①平均佇列長度小於最小門限——把新到達的分組放入佇列排隊。 ②平均佇列長度在最小門限與最大門限之間——則按照某一概率將分組丟棄。 ③平均佇列長度大於最大門限——丟棄新到達的分組。 RED不是等到已經發生擁塞後才把所有佇列尾部的分組全部丟棄,而是在檢測到網路擁塞的早期徵兆時(即路由器的平均佇列長度超過一定門限值時),以概率p隨機丟棄分組,讓擁塞控制只在個別的TCP連線上執行,因而避免全域性性的擁塞控制。 RED的關鍵就是選擇三個引數最小門限、最大門限、丟棄概率和計算平均佇列長度。最小門線必須足夠大,以保證路由器的輸出鏈路有較高的利用率。而最大門限和最小門限只差也應該足夠大,是的在一個TCP往返時間RTT中佇列的正常增長仍在最大門限之內。經驗證明:使最大門限等於最小門限的二倍是合適的。 平均佇列長度採用加權平均的方法計算平均佇列長度,這和往返時間(RTT)的計算策略是一樣的。