TCP慢啟動與擁塞控制筆記

yushuifirst發表於2015-06-01

TCP慢啟動與擁塞控制筆記

流量控制

傳輸資料的時候,如果傳送方傳輸的資料量超過了接收方的處理能力,那麼接收方會出現丟包。為了避免出現此類問題,流量控制要求資料傳輸雙方在每次互動時宣告各自的接收視窗「rwnd」大小,用來表示自己最大能儲存多少資料,這主要是針對接收方而言的,通俗點兒說就是讓傳送方知道接收方能吃幾碗飯,如果視窗衰減到零,那麼就說明吃飽了,必須消化消化,如果硬撐的話說不定會大小便失禁,那就是丟包了。

接收方和傳送方的稱呼是相對的,如果站在使用者的角度看:當瀏覽網頁時,資料以下行為主,此時客戶端是接收方,服務端是傳送方;當上傳檔案時,資料以上行為主,此時客戶端是傳送方,服務端是接收

慢啟動

雖然流量控制可以避免傳送方過載接收方,但是卻無法避免過載網路,這是因為接收視窗「rwnd」只反映了伺服器個體的情況,卻無法反映網路整體的情況。

為了避免過載網路的問題,慢啟動引入了擁塞視窗「cwnd」的概念,用來表示傳送方在得到接收方確認前,最大允許傳輸的未經確認的資料。「cwnd」同「rwnd」相比不同的是:它只是傳送方的一個內部引數,無需通知給接收方,其初始值往往比較小,然後隨著資料包被接收方確認,視窗成倍擴大,有點類似於拳擊比賽,開始時不瞭解敵情,往往是次拳試探,慢慢心裡有底了,開始逐漸加大重拳進攻的力度。

在慢啟動的過程中,隨著「cwnd」的增加,可能會出現網路過載,其外在表現就是丟包,一旦出現此類問題,「cwnd」的大小會迅速衰減,以便網路能夠緩過來。

說明:網路中實際傳輸的未經確認的資料大小取決於「rwnd」和「cwnd」中的小值。

擁塞避免

從慢啟動的介紹中,我們能看到,傳送方通過對「cwnd」大小的控制,能夠避免網路過載,在此過程中,丟包與其說是一個網路問題,倒不如說是一種反饋機制,通過它我們可以感知到發生了網路擁塞,進而調整資料傳輸策略,實際上,這裡還有一個慢啟動閾值「ssthresh」的概念,如果「cwnd」小於「ssthresh」,那麼表示在慢啟動階段;如果「cwnd」大於「ssthresh」,那麼表示在擁塞避免階段,此時「cwnd」不再像慢啟動階段那樣呈指數級整整,而是趨向於線性增長,以期避免網路擁塞。

對於一個給定的連線,初始化的cwnd為1個報文段,ssthresh初始值為65535位元組。當擁塞發生時(收到確認或者收到重複確認)ssthresh被設定為當前視窗大小的一半,(cwnd和接收方通告視窗大小的最小值,但最少為2個報文段),此外,如果是超時引起的擁塞,則cwnd被設定為1個報文段(這就是慢啟動)。

當心的資料被對方確認的時候,就增加cwnd,但增加的方法依賴於我們是否正在進行慢啟動或者擁塞避免。如果cwnd小於或者等於ssthresh,則正在進行慢啟動,否則正在進行擁塞避免。慢啟動一直持續到我們回到當擁塞發生時所處位置一半的時候才停止,然後轉為執行擁塞避免。

擁塞避免演算法要求每次收到一個確認的時候將cwnd增加1個報文段。與慢啟動相比這是一種加性增長。

如何調整「rwnd」到一個合理值

有很多人都遇到過網路傳輸速度過慢的問題,比如說明明是百兆網路,其最大傳輸資料的理論值怎麼著也得有個十兆,但是實際情況卻相距甚遠,可能只有一兆。此類問題如果剔除奸商因素,多半是由於接收視窗「rwnd」設定不合理造成的。

實際上接收視窗「rwnd」的合理值取決於BDP的大小,也就是頻寬和延遲的乘積。假設頻寬是 100Mbps,延遲是 100ms,那麼計算過程如下:

BDP = 100Mbps * 100ms = (100 / 8) * (100 / 1000) = 1.25MB

此問題下如果想最大限度提升吞度量,接收視窗「rwnd」的大小不應小於 1.25MB。說點引申的內容:TCP使用16位來記錄視窗大小,也就是說最大值是64KB,如果超過它,就需要使用tcp_window_scaling機制。

相關文章