什么是TCP擁塞控制算法?

最近花了些時(shí)間在學(xué)習(xí)TCP/IP協(xié)議上拨脉,首要原因是由于本人長(zhǎng)期以來(lái)對(duì)TCP/IP的認(rèn)識(shí)就只限于三次握手四次分手上哆姻,所以希望深入了解一下。再者玫膀,TCP/IP和Linux系統(tǒng)層級(jí)的很多設(shè)計(jì)都可以用于中間件系統(tǒng)架構(gòu)上矛缨,比如說(shuō)TCP 擁塞控制算法也可以用在以響應(yīng)時(shí)間來(lái)限流的中間件上。更深一層帖旨,像TCP/IP協(xié)議這種基礎(chǔ)知識(shí)和原理性的技術(shù)箕昭,都是經(jīng)過(guò)長(zhǎng)時(shí)間的考驗(yàn)的,都是前人智慧的結(jié)晶解阅,可以給大家很多啟示和幫助落竹。

本文中會(huì)出現(xiàn)一些縮寫,因?yàn)槠鶈?wèn)題货抄,無(wú)法每個(gè)都進(jìn)行解釋筋量,如果你不明白它的含義,請(qǐng)自己去搜索了解碉熄,做一個(gè)主動(dòng)尋求知識(shí)的人桨武。

TCP協(xié)議有兩個(gè)比較重要的控制算法,一個(gè)是流量控制锈津,另一個(gè)就是阻塞控制呀酸。

TCP協(xié)議通過(guò)滑動(dòng)窗口來(lái)進(jìn)行流量控制,它是控制發(fā)送方的發(fā)送速度從而使接受者來(lái)得及接收并處理琼梆。而擁塞控制作用于整體網(wǎng)絡(luò)性誉,它是防止過(guò)多的包被發(fā)送到網(wǎng)絡(luò)中,避免出現(xiàn)網(wǎng)絡(luò)負(fù)載過(guò)大茎杂,網(wǎng)絡(luò)擁塞的情況错览。

擁塞算法需要掌握其狀態(tài)機(jī)和四種算法。擁塞控制狀態(tài)機(jī)的狀態(tài)有五種煌往,分別是:"Open倾哺,Disorder、CWR刽脖、Recovery和Loss狀態(tài)"羞海。四個(gè)算法為"慢啟動(dòng),擁塞避免曲管,擁塞發(fā)生時(shí)算法和快速恢復(fù)"却邓。

Congestion Control State Machine

和TCP一樣,擁塞控制算法也有其狀態(tài)機(jī)院水。當(dāng)發(fā)送方收到一個(gè)ACK時(shí)腊徙,Linux TCP通過(guò)狀態(tài)機(jī)的狀態(tài)來(lái)決定其接下來(lái)的行為简十,是應(yīng)該降低擁塞窗口cwnd大小,或者保持cwnd不變撬腾,還是繼續(xù)增加cwnd勺远。如果處理不當(dāng),可能會(huì)導(dǎo)致丟包或者超時(shí)时鸵。

1胶逢、Open狀態(tài)

Open狀態(tài)是擁塞控制狀態(tài)機(jī)的默認(rèn)狀態(tài)。這種狀態(tài)下饰潜,當(dāng)ACK到達(dá)時(shí)初坠,發(fā)送方根據(jù)擁塞窗口cwnd(Congestion Window)是小于還是大于慢啟動(dòng)閾值ssthresh(slow start threshold),來(lái)按照慢啟動(dòng)或者擁塞避免算法來(lái)調(diào)整擁塞窗口彭雾。

2碟刺、Disorder狀態(tài)

當(dāng)發(fā)送方檢測(cè)到DACK(重復(fù)確認(rèn))或者SACK(選擇性確認(rèn))時(shí),狀態(tài)機(jī)將轉(zhuǎn)變?yōu)镈isorder狀態(tài)薯酝。在此狀態(tài)下半沽,發(fā)送方遵循飛行(in-flight)包守恒原則,即一個(gè)新包只有在一個(gè)老包離開(kāi)網(wǎng)絡(luò)后才發(fā)送吴菠,也就是發(fā)送方收到老包的ACK后者填,才會(huì)再發(fā)送一個(gè)新包。

3做葵、CWR狀態(tài)

發(fā)送方接收到一個(gè)顯示擁塞通知時(shí)占哟,并不會(huì)立刻減少擁塞窗口cwnd,而是每收到兩個(gè)ACK就減少一個(gè)段酿矢,直到窗口的大小減半為止榨乎。當(dāng)cwnd正在減小并且網(wǎng)絡(luò)中有沒(méi)有重傳包時(shí),這個(gè)狀態(tài)就叫CWR(Congestion Window Reduced瘫筐,擁塞窗口減少)狀態(tài)蜜暑。CWR狀態(tài)可以轉(zhuǎn)變成Recovery或者Loss狀態(tài)。

4策肝、Recovery狀態(tài)

當(dāng)發(fā)送方接收到足夠(推薦為三個(gè))的DACK(重復(fù)確認(rèn))后肛捍,進(jìn)入該狀態(tài)。在該狀態(tài)下驳糯,擁塞窗口cnwd每收到兩個(gè)ACK就減少一個(gè)段(segment)篇梭,直到cwnd等于慢啟動(dòng)閾值ssthresh,也就是剛進(jìn)入Recover狀態(tài)時(shí)cwnd的一半大小酝枢。?發(fā)送方保持 Recovery 狀態(tài)直到所有進(jìn)入 Recovery狀態(tài)時(shí)正在發(fā)送的數(shù)據(jù)段都成功地被確認(rèn),然后發(fā)送方恢復(fù)成Open狀態(tài)悍手,重傳超時(shí)有可能中斷 Recovery 狀態(tài)帘睦,進(jìn)入Loss狀態(tài)袍患。

5、Loss狀態(tài)

當(dāng)一個(gè)RTO(重傳超時(shí)時(shí)間)到期后竣付,發(fā)送方進(jìn)入Loss狀態(tài)诡延。所有正在發(fā)送的數(shù)據(jù)標(biāo)記為丟失,擁塞窗口cwnd設(shè)置為一個(gè)段(segment)古胆,發(fā)送方再次以慢啟動(dòng)算法增大擁塞窗口cwnd肆良。

Loss 和 Recovery 狀態(tài)的區(qū)別是:Loss狀態(tài)下,擁塞窗口在發(fā)送方設(shè)置為一個(gè)段后增大逸绎,而 Recovery 狀態(tài)下惹恃,擁塞窗口只能被減小。Loss 狀態(tài)不能被其他的狀態(tài)中斷棺牧,因此巫糙,發(fā)送方只有在所有 Loss 開(kāi)始時(shí)正在傳輸?shù)臄?shù)據(jù)都得到成功確認(rèn)后,才能退到 Open 狀態(tài)颊乘。

四大算法

擁塞控制主要是四個(gè)算法:

1)慢啟動(dòng);

2)擁塞避免;

3)擁塞發(fā)生;

4)快速恢復(fù)参淹。

這四個(gè)算法不是一天都搞出來(lái)的,這個(gè)四算法的發(fā)展經(jīng)歷了很多時(shí)間乏悄,到今天都還在優(yōu)化中浙值。

慢熱啟動(dòng)算法 – Slow Start

所謂慢啟動(dòng),也就是TCP連接剛建立檩小,一點(diǎn)一點(diǎn)地提速亥鸠,試探一下網(wǎng)絡(luò)的承受能力,以免直接擾亂了網(wǎng)絡(luò)通道的秩序识啦。

慢啟動(dòng)算法

  1. 负蚊、連接建好的開(kāi)始先初始化擁塞窗口cwnd大小為1,表明可以傳一個(gè)MSS大小的數(shù)據(jù)颓哮。

2)家妆、 每當(dāng)收到一個(gè)ACK,cwnd大小加一冕茅,呈線性上升伤极。

3)、 每當(dāng)過(guò)了一個(gè)往返延遲時(shí)間RTT(Round-Trip Time)姨伤,cwnd大小直接翻倍哨坪,乘以2,呈指數(shù)上升乍楚。

4)当编、 還有一個(gè)ssthresh(slow start threshold),是一個(gè)上限徒溪,當(dāng)cwnd >= ssthresh時(shí)忿偷,就會(huì)進(jìn)入“擁塞避免算法”(后面會(huì)說(shuō)這個(gè)算法)金顿。

擁塞避免算法 – Congestion Avoidance

如同前邊說(shuō)的,當(dāng)擁塞窗口大小cwnd大于等于慢啟動(dòng)閾值ssthresh后鲤桥,就進(jìn)入擁塞避免算法揍拆。算法如下:

1)、收到一個(gè)ACK茶凳,則cwnd = cwnd + 1 / cwnd嫂拴。

2)、 每當(dāng)過(guò)了一個(gè)往返延遲時(shí)間RTT贮喧,cwnd大小加一筒狠。

過(guò)了慢啟動(dòng)閾值后,擁塞避免算法可以避免窗口增長(zhǎng)過(guò)快導(dǎo)致窗口擁塞塞淹,而是緩慢的增加調(diào)整到網(wǎng)絡(luò)的最佳值窟蓝。

擁塞狀態(tài)時(shí)的算法

一般來(lái)說(shuō),TCP擁塞控制默認(rèn)認(rèn)為網(wǎng)絡(luò)丟包是由于網(wǎng)絡(luò)擁塞導(dǎo)致的饱普,所以一般的TCP擁塞控制算法以丟包為網(wǎng)絡(luò)進(jìn)入擁塞狀態(tài)的信號(hào)运挫。對(duì)于丟包有兩種判定方式,一種是超時(shí)重傳RTO[Retransmission Timeout]超時(shí)套耕,另一個(gè)是收到三個(gè)重復(fù)確認(rèn)ACK梅鹦。

超時(shí)重傳是TCP協(xié)議保證數(shù)據(jù)可靠性的一個(gè)重要機(jī)制求妹,其原理是在發(fā)送一個(gè)數(shù)據(jù)以后就開(kāi)啟一個(gè)計(jì)時(shí)器,在一定時(shí)間內(nèi)如果沒(méi)有得到發(fā)送數(shù)據(jù)報(bào)的ACK報(bào)文,那么就重新發(fā)送數(shù)據(jù)悼院,直到發(fā)送成功為止掌栅。

但是如果發(fā)送端接收到3個(gè)以上的重復(fù)ACK半开,TCP就意識(shí)到數(shù)據(jù)發(fā)生丟失混滔,需要重傳。這個(gè)機(jī)制不需要等到重傳定時(shí)器超時(shí)征冷,所以叫做快速重傳择膝,而快速重傳后沒(méi)有使用慢啟動(dòng)算法,而是擁塞避免算法检激,所以這又叫做快速恢復(fù)算法肴捉。

超時(shí)重傳RTO[Retransmission Timeout]超時(shí),TCP會(huì)重傳數(shù)據(jù)包叔收。TCP認(rèn)為這種情況比較糟糕齿穗,反應(yīng)也比較強(qiáng)烈:

  • 由于發(fā)生丟包,將慢啟動(dòng)閾值ssthresh設(shè)置為當(dāng)前cwnd的一半饺律,即ssthresh = cwnd / 2.

  • cwnd重置為1

  • 進(jìn)入慢啟動(dòng)過(guò)程

最為早期的TCP Tahoe算法就使用上述處理辦法窃页,但是由于一丟包就一切重來(lái),導(dǎo)致cwnd重置為1,十分不利于網(wǎng)絡(luò)數(shù)據(jù)的穩(wěn)定傳遞腮出。

所以帖鸦,TCP Reno算法進(jìn)行了優(yōu)化芝薇。當(dāng)收到三個(gè)重復(fù)確認(rèn)ACK時(shí)胚嘲,TCP開(kāi)啟快速重傳Fast Retransmit算法,而不用等到RTO超時(shí)再進(jìn)行重傳:

  • cwnd大小縮小為當(dāng)前的一半

  • ssthresh設(shè)置為縮小后的cwnd大小

  • 然后進(jìn)入快速恢復(fù)算法Fast Recovery洛二。

快速恢復(fù)算法 – Fast Recovery

TCP Tahoe是早期的算法馋劈,所以沒(méi)有快速恢復(fù)算法,而Reno算法有晾嘶。在進(jìn)入快速恢復(fù)之前妓雾,cwnd和ssthresh已經(jīng)被更改為原有cwnd的一半±萦兀快速恢復(fù)算法的邏輯如下:

  • cwnd = cwnd + 3 * MSS械姻,加3 * MSS的原因是因?yàn)槭盏?個(gè)重復(fù)的ACK。

  • 重傳DACKs指定的數(shù)據(jù)包机断。

  • 如果再收到DACKs楷拳,那么cwnd大小增加一。

  • 如果收到新的ACK吏奸,表明重傳的包成功了欢揖,那么退出快速恢復(fù)算法。將cwnd設(shè)置為ssthresh奋蔚,然后進(jìn)入擁塞避免算法她混。

如圖所示,第五個(gè)包發(fā)生了丟失泊碑,所以導(dǎo)致接收方接收到三次重復(fù)ACK坤按,也就是ACK5。所以將ssthresh設(shè)置為當(dāng)時(shí)cwnd的一半馒过,也就是6/2 = 3臭脓,cwnd設(shè)置為3 + 3 = 6。然后重傳第五個(gè)包沉桌。當(dāng)收到新的ACK時(shí)谢鹊,也就是ACK11,則退出快速恢復(fù)階段留凭,將cwnd重新設(shè)置為當(dāng)前的ssthresh佃扼,也就是3,然后進(jìn)入擁塞避免算法階段蔼夜。

后記

本文為大家大致描述了TCP擁塞控制的一些機(jī)制兼耀,但是這些擁塞控制還是有很多缺陷和待優(yōu)化的地方,業(yè)界也在不斷推出新的擁塞控制算法,比如說(shuō)谷歌的BBR瘤运。這些我們后續(xù)也會(huì)繼續(xù)探討窍霞,請(qǐng)大家繼續(xù)關(guān)注。

寫在最后:

歡迎大家關(guān)注我新開(kāi)通的公眾號(hào)【風(fēng)平浪靜如碼】拯坟,海量Java相關(guān)文章但金,學(xué)習(xí)資料都會(huì)在里面更新,整理的資料也會(huì)放在里面郁季。

覺(jué)得寫的還不錯(cuò)的就點(diǎn)個(gè)贊冷溃,加個(gè)關(guān)注唄!點(diǎn)關(guān)注梦裂,不迷路似枕,持續(xù)更新!D昴凿歼!

海量面試、架構(gòu)資料分享

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冗恨,一起剝皮案震驚了整個(gè)濱河市答憔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌派近,老刑警劉巖攀唯,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異渴丸,居然都是意外死亡侯嘀,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門谱轨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)戒幔,“玉大人,你說(shuō)我怎么就攤上這事土童∈ィ” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵献汗,是天一觀的道長(zhǎng)敢订。 經(jīng)常有香客問(wèn)我,道長(zhǎng)罢吃,這世上最難降的妖魔是什么楚午? 我笑而不...
    開(kāi)封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮尿招,結(jié)果婚禮上矾柜,老公的妹妹穿的比我還像新娘阱驾。我一直安慰自己,他們只是感情好怪蔑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布里覆。 她就那樣靜靜地躺著,像睡著了一般缆瓣。 火紅的嫁衣襯著肌膚如雪喧枷。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天捆愁,我揣著相機(jī)與錄音割去,去河邊找鬼窟却。 笑死昼丑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的夸赫。 我是一名探鬼主播菩帝,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼茬腿!你這毒婦竟也來(lái)了呼奢?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤切平,失蹤者是張志新(化名)和其女友劉穎握础,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悴品,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡禀综,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了苔严。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片定枷。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖届氢,靈堂內(nèi)的尸體忽然破棺而出欠窒,到底是詐尸還是另有隱情,我是刑警寧澤退子,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布岖妄,位于F島的核電站,受9級(jí)特大地震影響寂祥,放射性物質(zhì)發(fā)生泄漏荐虐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一壤靶、第九天 我趴在偏房一處隱蔽的房頂上張望缚俏。 院中可真熱鬧,春花似錦、人聲如沸忧换。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)亚茬。三九已至酪耳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刹缝,已是汗流浹背碗暗。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梢夯,地道東北人言疗。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像颂砸,于是被迫代替她去往敵國(guó)和親噪奄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 首先人乓,我們需要知道TCP在網(wǎng)絡(luò)ISO的七層模型中的第四層——Transport層勤篮,IP在第三層——Network層...
    CodeKing2017閱讀 1,112評(píng)論 0 4
  • 在上一篇文章中,講了通過(guò)滑動(dòng)窗口實(shí)現(xiàn)發(fā)送方和接收方之間一對(duì)一的流量控制色罚。這次我們來(lái)看一下 TCP 協(xié)議是如何對(duì)網(wǎng)絡(luò)...
    小小小超子閱讀 1,768評(píng)論 0 3
  • 運(yùn)輸層協(xié)議概述 從通信和信息處理的角度看碰缔,運(yùn)輸層向它上面的應(yīng)用層提供通信服務(wù),它屬于面向通信部分的最高層戳护,同時(shí)也是...
    srtianxia閱讀 2,408評(píng)論 0 2
  • 引言 計(jì)算機(jī)網(wǎng)絡(luò)中的帶寬金抡、交換結(jié)點(diǎn)中的緩存和處理機(jī)等,都是網(wǎng)絡(luò)的資源姑尺。在某段時(shí)間竟终,若對(duì)網(wǎng)絡(luò)中某一資源的需求超過(guò)了該...
    qyoyoz閱讀 576評(píng)論 0 0
  • 《散落的夢(mèng)境章節(jié)·第一篇》——兄弟,有我呢切蟋! 文/飛揚(yáng) 我們是大學(xué)最好的室友统捶,你叫我逗逼,我叫你傻逼柄粹。 我們每天一...
    飛揚(yáng)Xavier閱讀 426評(píng)論 5 2