1. 程式人生 > >讓人非常easy誤解的TCP擁塞控制算法

讓人非常easy誤解的TCP擁塞控制算法

先來 模塊 階段 聯網 進程 分布 detail 體驗 尊重

正文

非常多人會覺得一個好的TCP擁塞控制算法會讓連接加速,這樣的觀點是錯誤的。恰恰相反,全部的擁塞控制算法都是為了TCP能夠在貪婪的時候懸崖勒馬,大多數時候。擁塞控制是減少了數據發送的速度。

我在本文中會針對近期跟業內朋友之間的聊天記錄。總結出三言兩語。
TCP擁塞控制的終極目標絕對不是加快數據發送的速度,這樣的理解非常自私且膚淺!它的終結目標是在公平占有帶寬的前提下無限度提高帶寬的利用率!


假設你僅僅關註一個獨立的TCP連接本身,那麽你或許永遠都不可能設計出什麽比較好的算法,但假設你不從一個獨立的連接入手,貌似更加虛無飄渺,畢竟你能拿到且駕馭的僅僅有一個連接!

考慮一個進程調度器的設計,從2.6.23開始。大家普遍覺得Linux調度器迎來了一個新的階段,即CFS階段,相比之下。O(1)調度器僅僅像是一個過渡,而之前的O(n)調度器就略顯0基礎了。當時我也關註了這個新調度器好一陣子,正如我這段時間關註TCP BBR一樣...So,我們來看一下CFS究竟好在哪裏,以至於它能夠占領Linux默認調度器這頭把交椅。


首先我們反問。CFS讓進程執行的速度更快了嗎?非也,有點經驗的都知道。對於追求高吞吐的環境,CFS反而讓進程執行的速度更慢了。比較膚淺的認知角度,一般非常easy將“好”和“快”緊密聯系在一起,但事實上。站在更高的層次。你看到的將不再是一個獨立的進程,而是一整機器裏面全部的進程!

CFS究竟好在哪裏?
從其名字上就能夠看出,其優點在於“全然公平”!

它治療了O(1)調度器中差點兒全部的不公平調度導致的癥狀。比方IO消耗型與交互進程之間的搶占與饑餓問題,比方調度粒度問題。等等全部這些問題,引入一個虛擬時鐘後。公平性得到了非常精確的度量。這些問題終於得到了解決。

從開始到最後,沒有不論什麽獨立的進程“被加快了執行速度”!
終於,CFS讓全部進程在公平持有CPU時間的前提下,讓CPU盡可能滿負荷運轉,即提高了CPU的利用率。整個過程沒有毛刺,非常平滑。
----------------------------------------------------

間中,我們來看看平滑取代毛刺的優點,眼睛僅僅要直視就是那麽的帥!《德國佬又火了!奧迪終於把球形輪胎造了出來…》!


----------------------------------------------------
如今回到TCP本身,BBR和當年的CFS一樣,引起了眾人的關註。我想我已經引出了“怎樣設計一個好的TCP擁塞控制算法”的思路了。


站在全球互聯網上空往下看。你看到的是全部的TCP連接,而不僅僅是你的機器上建立的那一個或者那幾個。

這就是格局不同,你的偏見自然也就消除了。上海自然要和北京競爭。但北京不這麽看,不管哪裏好了,都是它北京的,不是嗎?怎樣讓全部的TCP連接公平共享全部的互聯網帶寬,是TCP擁塞控制算法的根本!註意兩個關鍵點,其一。公平地共享,其二,盡可能全部的帶寬。


這個問題是一個世界難題,沒有進程調度器那麽簡單!
進程調度器是作用於一個CPU的。或者簡單點說,作用於一臺機器。

這臺機器就在你的手上。你,也就是調度器的設計者全然能夠看清楚當前機器裏發生的一切,一切不公平癥狀,一切浪費現象能夠讓設計者盡收眼底,你能夠強制性拿一個進程的資源給予還有一個進程。你也能夠殺死過於貪婪的進程...對於TCP而言,根本沒有一個能夠站在全球互聯網往下看的高人,TCP擁塞控制是全然分布式的,每個設計者都僅僅能看到自己機器上的那一部分連接。
然而,TCP擁塞控制之所以如此難並非什麽所謂分布式導致的。事實上分布式一點也不難,難點在於TCP擁塞控制總是被誤解。所以說在設計算法的時候。稍不留神就會南轅北轍。本來是避免擁塞的,實際上是添堵的。


為什麽會被誤解?事實上凱撒早就說過,人們總是看到自己希望看到的。

這句話還有還有一層意思,人們樂於把自己看到的局部當成全部。

人們能夠一眼看到一整機器的進程。所以設計出一個好的進程調度器是非常easy的,所以CFS出現了。可是大家看不到全部的TCP連接。大家看到的僅僅是自己的TCP連接,所以大家僅僅能臆測,我好。你也好。至於算法是否添堵,可能全然不是出於惡意,而全然是目光的短淺和格局之不高導致的。


一個正確的,且好的TCP擁塞控制算法應該是顧及全部的連接的,假設TCP不夠快,那就應該讓全部TCP都提速,這點體現了帶寬利用率的提高。假設TCP已經足夠快。那不論什麽連接都不能更快,這點體現了公平性。

換成人話非常簡單。假設你覺得開車走省道慢,那就上快速,假設你已經在快速公路上,請不要變道超車。
多麽簡單的道理,可還是能看到道路上變道超車的,我可能表達有問題,是全部的司機都在玩變道超車,假設讓這些人來設計TCP擁塞控制算法,會好到哪裏去呢?不幸的是。世界上TCP單邊加速玩的最火的那批人,和這批中國好司機是同一批人,不管什麽資源,唯一的目標除了搶,還是搶。
事實上。我並非一個道德說教者。說什麽人人為我,我為人人的算法才是一個好的算法,說的就好像我自己做到了似的...
我是被兩位大師罵了才知錯就改了。事實上我也走火入魔過...
前一段時間吧。我改動了一個擁塞算法。呈給一位大師評解,姑且叫大師1吧。值得"炫耀"的就是我這個算法非常快,甚至比BBR還要快,可是被惡損了一頓,我的算法“競賽肯定第一”,可是卻“不負責任”...這樣的是毀人品的算法。後來,我試著讓兩個或者多個執行同一個算法的流一起數據傳輸,果然...一些流會瞬間把剩余的流帶寬壓榨到0!連敵友都不分了,簡直就是流氓算法啊!

這個算法從此也就閱後即焚了,全然不可用。
...
假設這還不算,那麽還有一位大師2則徹底讓我覺得自己根本就狗屁都不懂。
這位大師在國外,跟我有時差,且能讀中文但不寫中文,我與之相反。我是能讀英文但寫起來費勁。所以僅僅能郵件交流。

主題還是擁塞控制。我由於急功近利僅僅是問了“怎麽讓TCP數據發送速度更快”這樣的問題,答案非常簡單。忽略擁塞控制並補償性重傳即可。然後我就寫了一個“忽略擁塞控制的擁塞控制算法”。而且挑釁般的作為回應。然後的郵件裏就出現了fxxk詞匯,還有suck...說我根本就不懂主要的原則,並力勸我辭去工作回家細致學習和思考。

我都快哭了。
...........
大師2的教導在大師1之前。可是大師1給了我詳細怎麽做的方向和方法。我除了發自內心的感謝之外,能做的就是寫一些“抨擊TCP擁塞控制算法”的文章來把人人為我,我為人人的基督教理念傳遞給很多其他的人。

出於對兩位大師以及各路朋友的尊重,我不會貼出與之相關的代碼,郵件原文以及聊天記錄。消化加工後的理念,由我這裏直接始發。


BBR

本文的最後,我通過BBR算法略微聊一下什麽樣的算法是正確的算法。
BBR和當年的CFS一樣,這個我已經說過了。可是BBR眼下仍處在比較0基礎的階段,起初呢,我覺得它的問題在於:
1.收斂太慢,即不會即時降速降窗。而是要在幾個RTT內完畢;
2.向上探測太遲。難道問題1是對這個的補償也說不準;
3.大BDP緩存下的搶占性有待商榷;
4.BBR依托的SDN基礎設施...
...

能夠看到,這樣的最初的領悟體現了我個人多麽深厚的技術功底。然而後來。經大師指點,我才發現。原來BBR的最大問題在於,它引入的新擁塞控制框架非常easy被誤用,詳細的請參見http://blog.csdn.net/dog250/article/details/54754784
假設幾個三流的比我還差的人使用新框架寫算法,那麽互聯網崩潰指日可待。幸運的是。即便崩潰,也僅僅是國內的互聯網崩潰,在這個領域,國外的月亮就是圓的,畢竟人家比我們受教育程度更深。懂得博弈理論。即便從自私者的角度來看。損人不利己的事情也是做不來的。

值得註意的是,有知識不代表有文化。我一直覺得國內的大學事實上就是技校,特別是華中科技大學。差點兒是定向給華為,BAT等巨頭培養高級技工的。


回到BBR。對於BBR帶來的新框架,最嚴重的是,之前有人拼速度拼重傳的時候,會有prr降窗。這點是不受算法模塊控制的。如今好了,直接寫個回調,全然繞開了降窗。大家都去添堵去了TCP設計的原則層面,RFC裏貌似也把公平性提到了至高的地位。由於假設不把公平性作為基本原則。那麽整個環將不是閉合的。帶寬資源早晚會用盡,此時盲目的AI非MD過程將會促使大家都想往前搶,最後誰也過不去,如此一來。互聯網將全然不可用!基於這點。全部搞“TCP單邊加速”的個人和廠商都是在做鉆空子的壞事,其出發點就是錯誤的。

當然。這類廠商的出發點往往不是TCP層面的。而是業務層面的,這倒是無可厚非。畢竟不是一個領域,我也無權過問太多,TCP對於它們而言僅僅是工具。真到哪天互聯網崩潰了。他們還是會用卡車運硬盤的方式來進行數據傳輸的,到時候,快速公路上堵的水泄不通的運硬盤的卡車與TCP一樣,也僅僅是個工具,而已。
----------------------
怎麽樣的做法是正確的呢?
先來介紹一個君子算法,即LEDBAT算法,能夠看看http://www.rfc-base.org/txt/rfc-6817.txt,其wiki是https://zh.wikipedia.org/wiki/LEDBAT
它的思想在搞“加速”的那幫人看來,事實上有點搞笑。它的存在是為了填補CUBIC之流不Bloat Buffer時候的空隙的,一旦有其他流量造成了排隊,LEDBAT立即騰地方退讓。這樣的算法是應該被“加速者”第一時間拋棄的算法,可是它在iOS和Win10裏卻大行其道,LEDBAT主要用於軟件更新,這樣的事一般能夠在後臺默默進行。優先級比較低。所以發明一個後臺靜默的君子式LEDBAT算法。實則是在提高帶寬利用率上無所不用其極啊。然而這個算法又不會跟其他的流量爭搶帶寬,絲毫不會應該高優先級流量的公平性,難道不是非常帥的算法嗎?LEDBAT在表達的是,你們去前面堵著去吧,我沒你們重要,我慢慢走即可。。。
BBR不是君子式算法,它是要參與公平競爭的,我不主動欺負人。可是被人欺負,我不會怕事的。因此BBR在LEDBAT上添加了Probe More的過程。同一時候,與LEDBAT退讓不同,BBR將其改成了輕柔緩和的Drain Less。


全部這些都不是近期剛剛出現的,在此之前,Vegas算法則代表了一種正確的做法,它終於沒有上位是由於Vegas部署有個前提,那就是同一時間全部部署成Vegas,然而這是不可能的。僅僅要有Reno或者CUBIC在,Vegas的“正確做法”就會吃虧。

現實就是這樣,劣幣驅良幣。CUBIC明明是錯誤的算法,但由於它能夠利用率非常低但非常簡單的方法快速收斂到可用帶寬,所以就一直是大家認可的算法。全部人都在默默忍受著Bufferbloat,而這個問題帶來的額外排隊延遲會大大減少交互式TCP連接的交互體驗,同一時候嚴重影響實時性的協議。比方NTP之類。
CUBIC是一定會堵路的,Buffer被堵了之後。交互應用的數據就會被排隊,時延添加,交互性自然下降。
我一直好奇的問題是。為什麽Reno。CUBIC之流在經過慢啟動之後的AI增窗過程叫做擁塞避免,相反,這樣的盲目的一路走到黑的增窗方式一定會導致擁塞的,即擁塞不可避免。這個過程是玷汙了“擁塞避免”這個詞呢,還是說僅僅是一個定義呢?以下的一篇文章給出答案,如今的時間是周六早上7點半,該睡一會兒了。

寫在最後的序:

“昨夜入城市。歸來淚滿襟”的那是傻逼,自己不養蠶便是了,幹嘛妒忌別人穿絲綢。


今天又是周末。又能夠半夜起來折騰,本文寫作開始於五點半,完畢於早七點二十,在此之前,我花了一個小時時間讀了《盧比孔河》之25頁。再之前的一個小時。我看了一些關於道路規劃的東西。主要在令人不安的電腦上...如今,本來我想睡一覺,然而睡不著。就想去登高望遠。僅僅可惜旁邊的山都太矮小了...自從甘孜歸來,深圳的山就成小土堆了...實際一點。去買菜。做飯才是解決之道。做什麽飯呢?哈哈。重慶帶來的老火鍋!

----我希望你能看到這篇文章。



讓人非常easy誤解的TCP擁塞控制算法