1. 程式人生 > 程式設計 >各種TCP擁塞控制演演算法

各種TCP擁塞控制演演算法

前言

自從TCP擁塞控制的概念提出以來,TCP擁塞控制演演算法經歷了一系列的演化。這裡根據網上的資料大致總結一下各個TCP擁塞控制演演算法。

TCP Tahoe/Reno

最初的實現,包括慢啟動、擁塞避免兩個部分。基於重傳超時(retransmission timeout/RTO)和重複確認為條件判斷是否發生了丟包。兩者的區別在於:Tahoe演演算法下如果收到三次重複確認,就進入快重傳立即重發丟失的資料包,同時將慢啟動閾值設定為當前擁塞視窗的一半,將擁塞視窗設定為1MSS,進入慢啟動狀態;而Reno演演算法如果收到三次重複確認,就進入快重傳,但不進入慢啟動狀態,而是直接將擁塞視窗減半,進入擁塞控制階段,這稱為“快恢復”。

而Tahoe和Reno演演算法在出現RTO時的措施一致,都是將擁塞視窗降為1個MSS,然後進入慢啟動階段。

TCP Vegas

TCP Vegas演演算法由 Lawrence Brakmo 和 Larry L. Peterson 在1994年提出,它和其他擁塞控制演演算法的不同之處在於Vegas演演算法並不急於丟包來判斷是否發生了擁塞,而是通過資料包延遲來判斷。Vegas通過RTT(roundtrip time)來決定增加或者減小擁塞視窗,它能夠擁塞將要發生時就避免擁塞,而不是等到擁塞已經發生之後再減小傳送速度,因此能夠減小重傳和超時的機率。Vegas演演算法與其他演演算法(比如Reno)共存時,會由於比其他演演算法更先降低傳送速率而出現公平性問題。

TCP New Reno

TCP New Reno主要改進了TCP Reno中快速恢復階段的重傳。

在Reno的快恢復中,一旦出現3次重複確認,TCP傳送方會重發資料包並設定定時器等待該重發資料包被確認。當重發的資料包被確認後,就立即退出快速恢復階段,進入擁塞控制階段。但如果一次擁塞中出現多個丟包,Reno會誤以為發生了多次擁塞而重複減小擁塞視窗導致傳送速率下降。

而在New Reno的快速恢復中,一旦出現3次重複確認,會記下出現重複確認時未確認的資料包的最大序列號,然後重發重複確認的資料包。如果有多個資料包丟失,則繼續重發丟失的資料包,知道最大序列號的資料包被確認才推出快恢復階段。

New Reno在低錯誤率時執行效率和“選擇確認”(Selective ACKnowledgement,SACK)相當,在高錯誤率仍優於Reno。

TCP BIC/CUBIC

TCP BIC(Binary Increase Congestion control)旨在優化高速高延遲網路(即“長肥網路”(long fat network,LFN))的擁塞控制,其擁塞視窗演演算法使用二分搜尋演演算法嘗試找到能長時間保持擁塞視窗最大值的值。Linux核心在2.6.8至2.6.18使用該演演算法作為預設TCP擁塞演演算法。

BIC演演算法採用二分查詢的方式來確定最大的視窗大小:如果發生丟包時視窗大小是W1,那麼最大視窗Wmax應該小於W1;這時將視窗縮小到W2(乘以一個係數,也就是乘法減小),那麼可以預期W1>Wmax>W2;這時再將視窗大小設定為(W1+W2)2(也就是二分查詢),即每收到一個ACK就把視窗大小設定為兩個界限的中點。

如果視窗大小已經無限逼近W1,說明網路狀況又變好了(可用頻寬增加了),這時BIC會嘗試往上尋找更大的Wmax。而在往上尋找時,BIC會映象的利用逼近當前Wmax的路徑去搜尋,也就是前面是如何先快後慢慢地靠近當前Wmax的,後面就反過來先慢後快地增長。

而CUBIC則是比BIC更溫和和系統化的分支版本,其使用三次函式代替二分演演算法作為其擁塞視窗演演算法(因為實際上BIC的搜尋曲線看起來就像一個三次函式,所以乾脆就寫一個三次函式來模擬曲線),並且使用函式拐點作為擁塞視窗的設定值。Linux核心在2.6.19後使用該演演算法作為預設TCP擁塞演演算法。

TCP Westwood/Westwood+

TCP Westwood改良自New Reno,不同於以往其他擁塞控制演演算法使用丟失來測量,其通過對確認包測量來確定一個“合適的傳送速度”,並以此調整擁塞視窗和慢啟動閾值。Westwood改良了慢啟動階段演演算法為“敏捷探測(Agile Probing)”,並且設計了一種持續探測擁塞視窗的方法來控制進入“敏捷探測”,使連線儘可能地使用更多的頻寬。Westwood+使用更長的頻寬估計間隔和優化的濾波器來修正Westwood對ACK壓縮場景對頻寬估計過高的問題。通過以上改良,TCP Westwood系列演演算法在有線網路和無線網路的擁塞控制上取得平衡,尤其研究中針對於無線通訊網路上。

Compound TCP

Compound TCP是微軟自己實現的TCP擁塞控制演演算法,通過同時維護兩個擁塞視窗,來實現在長肥網路有較好的效能而又不損失公平性。CTCP維護兩個擁塞視窗:一個常規的AIMD(英語:Additive increase/multiplicative decrease)視窗,以及一個基於延遲的視窗,最終實際使用的滑動視窗大小是這兩個視窗的和。AIMD視窗與Reno的增加方式相同;如果延遲小,基於延遲的視窗將迅速增加以提高網路的利用率。一旦經歷了排隊,延遲視窗將逐漸減小以補償增加的AIMD視窗。這樣的目的是保持兩者的總和大致恆定,使演演算法估計頻寬時延積的路徑。

TCP PRR

TCP PRR(TCP Proportional Rate Reduction )是旨在恢復期間提高傳送資料的準確性。該演演算法確保恢復後的擁塞視窗大小盡可能接近慢啟動閾值

TCP BBR

TCP BBR(Bottleneck Bandwidth and Round-trip propagation time)是由Google設計,於2016年釋出的擁塞演演算法。以往大部分擁塞演演算法是基於丟包來作為降低傳輸速率的訊號,而BBR則基於模型主動探測。該演演算法使用網路最近出站資料分組當時的最大頻寬和往返時間來建立網路的顯式模型。資料包傳輸的每個累積或選擇性確認用於生成記錄在資料包傳輸過程和確認返回期間的時間內所傳送資料量的取樣率。該演演算法認為隨著網路介面控制器逐漸進入千兆速度時,分組丟失不應該被認為是識別擁塞的主要決定因素,所以基於模型的擁塞控制演演算法能有更高的吞吐量和更低的延遲,可以用BBR來替代其他流行的擁塞演演算法,例如CUBIC。

總結

可以看出,TCP擁塞控制主要是:1、探測是否出現擁塞;2、出現擁塞時如何反應。

最初的演演算法是基於丟包來判斷是否發生了擁塞,一旦出現擁塞之後就降低傳送速率來避免擁塞。後面有出現了基於RTT判斷擁塞的演演算法,但是這種演演算法會因為太“君子”而提前減小傳送速率(讓出頻寬),從而可能被共存的其他演演算法進一步壓榨產生公平性問題。微軟的CTCP通過維護兩個視窗來避免這種公平性問題,一個AIMD的視窗來保證不被其他人壓榨,另一個基於延遲的視窗能夠保證有頻寬時能迅速提高來提高頻寬利用率。而BBR則直接採用主動探測的方式來判斷擁塞是否發生。

當出現擁塞之後,通常需要降低傳送速率來避免擁塞進一步加劇,而不同演演算法在這時的處理都不盡相同,最初的演演算法通過直接降低傳送速率到1來簡單處理,但是這種方式太過粗暴,後續的其他演演算法也都做了不同的嘗試。