一、何為擁塞
路由器無法處理高速到達的數據而被迫丟棄數據的現象叫做擁塞。
二、何為擁塞控制
TCP流量控制時為了平衡一個鏈接中接收方和發送方的速度匹配問題,當發送方發現發送速度大於接收方的接收速度時動態調整發送速度。
但是成千上萬的TCP鏈接共享着整個網絡基礎設施,當網絡上這些TCP都在傳輸數據時,網絡有可能就會擁塞,TCP的擁塞控制就是在傳輸自己數據的同時實時掌握整個網絡的負載,然后基於整個網絡的負載來動態調整自己的發送速度。
三、網絡擁塞的開銷
擁塞時路由器丟失數據,丟失后基於可靠性傳輸的機制,發送方會重傳數據,重傳會再次加大網絡負載,導致更大的開銷。
在多路由器的情況下,會導致更大的資源浪費,比如數據有A傳遞到B經過了三個路由器,結果被第三個路由器給丟棄了。這樣前兩個路由器的工作全被白白浪費。如下圖所示,R3擁塞,A--》B的數據到達R3之后最終被丟棄了,R1、R2的工作被白白浪費。
由此可見,擁塞控制勢在必行。
四、擁塞控制的基本方法
4.1 端到端的擁塞控制
網絡層不提供擁塞控制機制,主要依靠端系統對網絡的觀察來調整發送的速度最終完成擁塞的控制(比如端系統通過觀察丟包的情況來判斷)。TCP/IP就是通過端到端的方法來解決擁塞控制(讓TCP來控制,IP不管)。
核心:觀察,感知,調整,解決。TCP的擁塞控制方法。
4.2 網絡輔助的擁塞控制
由路由器告知發送方網絡是否擁塞,主要兩種:
- 路由器直接高速發送方網絡狀況
- 當發送擁塞時,路由器在當前報文中標識擁塞,當接收方拿到這個擁塞標識后,由接收方告知發送方網絡擁塞,這種方式至少要一個RTT發送方才能知道擁塞。
報文不詳細展開。
五、TCP擁塞控制方法
TCP擁塞控制屬於端到端的控制方法,其核心便是觀察感知網絡的擁塞狀態,然后調整發送速度。在TCP中引入了擁塞窗口(cwnd:congestion window),流量控制中引入了接收窗口(rwnd:receive window)。最終TCP的發送窗口為min{cwnd,rwnd}。
5.1 如何感知網絡?
對於TCP來說核心兩點:
- 丟包(超時,或者三次冗余ack)就代表網絡擁塞,需要減少cwnd的size。
- 確認代表網絡暢通,可以加大cwnd的size。確認的越快cwnd增加的越快(反之亦然)。自計時(self-clocking)
下面的即將要介紹的幾個方法都是基於上面的兩個核心來展開的。
5.2 慢啟動(Slow Start)
慢啟動就是TCP啟動后的發送速度慢慢的進行提速,這樣才能便於感知網絡的狀況。
慢啟動的核心算法:
- 剛開始cwnd=1個MSS(max segment size)
- 每當收到一個ack,cwnd=cwnd+1。這樣每過一個RTT。cwnd便會翻倍:cwnd=cwnd*2,這是指數級增加
- 當cwnd=ssthresh(慢啟動閾值,slow start threshold)時,停止指數級增加,進入避免擁塞流程。
5.3 擁塞避免
慢啟動時cwnd時指數級增長,當增長的到ssthresh后便進入避免擁塞。避免擁塞算法比較簡單:
- 每收到一個ack,cwnd=cwnd+1/cwnd;
- 由此可見,每過一個RTT。cwnd=cwnd+1
可見擁塞避免算法實際是將cwnd的增長由指數級增長變為了一個線性緩慢增長。如下圖所示。
5.4 擁塞發生(感知到擁塞)
TCP認為發生擁塞由兩種情況:
- 超時
- 收到連續三次相同的ACK(快速重傳的場景)
5.4.1 超時
TCP超時后的具體動作:
- ssthresh=cwnd/2
- cwnd=1
- 進入慢啟動流程
5.4.2 連續三次相同的ACK
- 進入快速恢復流程
5.5 快速恢復
收到三次連續相同的ACK,說明產生了丟包,但是能收到ACK,說明超時相對不是那么嚴重。所以針對這種情況,TCP的做法沒有超時那么激進:
- ssthresh=cwnd
- cwnd=cwnd/2+3,3代表連續收到了3個ACK,累加三個窗口大小。
- 進入擁塞避免流程
以上介紹了TCP擁塞控制的一個整體過程。本文完。