讓人很容易誤解的TCP擁塞控制算法
阿新 • • 發佈:2019-02-16
wiki 領域 意思 般的 希望 cpu bsp 個人 它的
TCP擁塞控制的終極目標絕對不是加快數據發送的速度,這種理解非常自私且膚淺!它的終結目標是在公平占有帶寬的前提下無限度提高帶寬的利用率!
如果你只關註一個獨立的TCP連接本身,那麽你也許永遠都不可能設計出什麽比較好的算法,但如果你不從一個獨立的連接入手,貌似更加虛無飄渺,畢竟你能拿到且駕馭的只有一個連接!
考慮一個進程調度器的設計,從2.6.23開始,大家普遍認為Linux調度器迎來了一個新的階段,即CFS階段,相比之下,O(1)調度器僅僅像是一個過渡,而之前的O(n)調度器就略顯初級了。當時我也關註了這個新調度器好一陣子,正如我這段時間關註TCP BBR一樣...So,我們來看一下CFS到底好在哪裏,以至於它可以占據Linux默認調度器這頭把交椅。
首先我們反問,CFS讓進程運行的速度更快了嗎?非也,有點經驗的都知道,對於追求高吞吐的環境,CFS反而讓進程運行的速度更慢了。比較膚淺的認知角度,一般很容易將“好”和“快”緊密聯系在一起,但事實上,站在更高的層次,你看到的將不再是一個獨立的進程,而是一整機器裏面所有的進程!CFS到底好在哪裏?
從其名字上就可以看出,其好處在於“完全公平”!它治療了O(1)調度器中幾乎所有的不公平調度導致的癥狀,比如IO消耗型與交互進程之間的搶占與饑餓問題,比如調度粒度問題,等等所有這些問題,引入一個虛擬時鐘後,公平性得到了非常精確的度量,這些問題最終得到了解決。從開始到最後,沒有任何獨立的進程“被加快了運行速度”!
最終,CFS讓所有進程在公平持有CPU時間的前提下,讓CPU盡可能滿負荷運轉,即提高了CPU的利用率。整個過程沒有毛刺,非常平滑。
----------------------------------------------------
間中,我們來看看平滑代替毛刺的好處,眼睛只要直視就是那麽的帥!《德國佬又火了!奧迪終於把球形輪胎造了出來…》!
----------------------------------------------------
現在回到TCP本身,BBR和當年的CFS一樣,引起了眾人的關註。我想我已經引出了“如何設計一個好的TCP擁塞控制算法”的思路了。
站在全球互聯網上空往下看,你看到的是所有的TCP連接,而不僅僅是你的機器上建立的那一個或者那幾個。這就是格局不同,你的偏見自然也就消除了。上海自然要和北京競爭,但北京不這麽看,不管哪裏好了,都是它北京的,不是嗎?如何讓所有的TCP連接公平共享全部的互聯網帶寬,是TCP擁塞控制算法的根本!註意兩個關鍵點,其一,公平地共享,其二,盡可能全部的帶寬。
這個問題是一個世界難題,沒有進程調度器那麽簡單!
進程調度器是作用於一個CPU的,或者簡單點說,作用於一臺機器。這臺機器就在你的手上,你,也就是調度器的設計者完全可以看清楚當前機器裏發生的一切,一切不公平癥狀,一切浪費現象可以讓設計者盡收眼底,你可以強制性拿一個進程的資源給予另一個進程,你也可以殺死過於貪婪的進程...對於TCP而言,根本沒有一個可以站在全球互聯網往下看的高人,TCP擁塞控制是完全分布式的,每一個設計者都只能看到自己機器上的那一部分連接!
然而,TCP擁塞控制之所以如此難並不是什麽所謂分布式導致的,其實分布式一點也不難,難點在於TCP擁塞控制總是被誤解,所以說在設計算法的時候,稍不留神就會南轅北轍,本來是避免擁塞的,實際上是添堵的。
為什麽會被誤解?其實凱撒早就說過,人們總是看到自己希望看到的。這句話還有另一層意思,人們樂於把自己看到的局部當成所有。人們可以一眼看到一整機器的進程,所以設計出一個好的進程調度器是很容易的,所以CFS出現了。但是大家看不到所有的TCP連接,大家看到的只是自己的TCP連接,所以大家只能臆測,我好,你也好。至於算法是否添堵,可能完全不是出於惡意,而完全是目光的短淺和格局之不高導致的。
一個正確的,且好的TCP擁塞控制算法應該是顧及所有的連接的,如果TCP不夠快,那就應該讓所有TCP都提速,這點體現了帶寬利用率的提高;如果TCP已經足夠快,那任何連接都不能更快,這點體現了公平性。換成人話非常簡單,如果你覺得開車走省道慢,那就上高速,如果你已經在高速公路上,請不要變道超車。
多麽簡單的道理,可還是能看到道路上變道超車的,我可能表達有問題,是所有的司機都在玩變道超車,如果讓這些人來設計TCP擁塞控制算法,會好到哪裏去呢?不幸的是,世界上TCP單邊加速玩的最火的那批人,和這批中國好司機是同一批人,無論什麽資源,唯一的目標除了搶,還是搶。
其實,我並非一個道德說教者,說什麽人人為我,我為人人的算法才是一個好的算法,說的就好像我自己做到了似的...
我是被兩位大師罵了才知錯就改了,其實我也走火入魔過...
前一段時間吧,我修改了一個擁塞算法,呈給一位大師評解,姑且叫大師1吧,值得"炫耀"的就是我這個算法非常快,甚至比BBR還要快,但是被惡損了一頓,我的算法“競賽肯定第一”,但是卻“不負責任”...這種是毀人品的算法。後來,我試著讓兩個或者多個運行同一個算法的流一起傳輸數據,果然...一些流會瞬間把剩余的流帶寬壓榨到0!連敵友都不分了,簡直就是流氓算法啊!這個算法從此也就閱後即焚了,完全不可用。
...
如果這還不算,那麽另一位大師2則徹底讓我覺得自己根本就狗屁都不懂。
這位大師在國外,跟我有時差,且能讀中文但不寫中文,我與之相反,我是能讀英文但寫起來費勁,所以只能郵件交流。主題還是擁塞控制,我由於急功近利只是問了“怎麽讓TCP數據發送速度更快”這樣的問題,答案很簡單,忽略擁塞控制並補償性重傳即可,然後我就寫了一個“忽略擁塞控制的擁塞控制算法”,並且挑釁般的作為回應。然後的郵件裏就出現了fxxk詞匯,還有suck...說我根本就不懂基本的原則,並力勸我辭去工作回家仔細學習和思考。我都快哭了。
...........
大師2的教導在大師1之前,但是大師1給了我具體怎麽做的方向和方法,我除了發自內心的感謝之外,能做的就是寫一些“抨擊TCP擁塞控制算法”的文章來把人人為我,我為人人的基督教理念傳遞給更多的人。出於對兩位大師以及各路朋友的尊重,我不會貼出與之相關的代碼,郵件原文以及聊天記錄,消化加工後的理念,由我這裏直接始發。
本文的最後,我通過BBR算法稍微聊一下什麽樣的算法是正確的算法。
BBR和當年的CFS一樣,這個我已經說過了。但是BBR目前仍處在比較初級的階段,起初呢,我認為它的問題在於:
1.收斂太慢,即不會即時降速降窗,而是要在幾個RTT內完成;
2.向上探測太遲。難道問題1是對這個的補償也說不準;
3.大BDP緩存下的搶占性有待商榷;
4.BBR依托的SDN基礎設施...
...
可以看到,這種最初的領悟體現了我個人多麽深厚的技術功底。然而後來,經大師指點,我才發現,原來BBR的最大問題在於,它引入的新擁塞控制框架很容易被誤用,具體的請參見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點半,該睡一會兒了。
“昨夜入城市,歸來淚滿襟”的那是傻逼,自己不養蠶便是了,幹嘛嫉妒別人穿絲綢。
正文
很多人會認為一個好的TCP擁塞控制算法會讓連接加速,這種觀點是錯誤的,恰恰相反,所有的擁塞控制算法都是為了TCP可以在貪婪的時候懸崖勒馬,大多數時候,擁塞控制是降低了數據發送的速度。
我在本文中會針對近期跟業內朋友之間的聊天記錄,總結出三言兩語。TCP擁塞控制的終極目標絕對不是加快數據發送的速度,這種理解非常自私且膚淺!它的終結目標是在公平占有帶寬的前提下無限度提高帶寬的利用率!
如果你只關註一個獨立的TCP連接本身,那麽你也許永遠都不可能設計出什麽比較好的算法,但如果你不從一個獨立的連接入手,貌似更加虛無飄渺,畢竟你能拿到且駕馭的只有一個連接!
考慮一個進程調度器的設計,從2.6.23開始,大家普遍認為Linux調度器迎來了一個新的階段,即CFS階段,相比之下,O(1)調度器僅僅像是一個過渡,而之前的O(n)調度器就略顯初級了。當時我也關註了這個新調度器好一陣子,正如我這段時間關註TCP BBR一樣...So,我們來看一下CFS到底好在哪裏,以至於它可以占據Linux默認調度器這頭把交椅。
首先我們反問,CFS讓進程運行的速度更快了嗎?非也,有點經驗的都知道,對於追求高吞吐的環境,CFS反而讓進程運行的速度更慢了。比較膚淺的認知角度,一般很容易將“好”和“快”緊密聯系在一起,但事實上,站在更高的層次,你看到的將不再是一個獨立的進程,而是一整機器裏面所有的進程!CFS到底好在哪裏?
從其名字上就可以看出,其好處在於“完全公平”!它治療了O(1)調度器中幾乎所有的不公平調度導致的癥狀,比如IO消耗型與交互進程之間的搶占與饑餓問題,比如調度粒度問題,等等所有這些問題,引入一個虛擬時鐘後,公平性得到了非常精確的度量,這些問題最終得到了解決。從開始到最後,沒有任何獨立的進程“被加快了運行速度”!
最終,CFS讓所有進程在公平持有CPU時間的前提下,讓CPU盡可能滿負荷運轉,即提高了CPU的利用率。整個過程沒有毛刺,非常平滑。
----------------------------------------------------
間中,我們來看看平滑代替毛刺的好處,眼睛只要直視就是那麽的帥!《德國佬又火了!奧迪終於把球形輪胎造了出來…》!
----------------------------------------------------
現在回到TCP本身,BBR和當年的CFS一樣,引起了眾人的關註。我想我已經引出了“如何設計一個好的TCP擁塞控制算法”的思路了。
站在全球互聯網上空往下看,你看到的是所有的TCP連接,而不僅僅是你的機器上建立的那一個或者那幾個。這就是格局不同,你的偏見自然也就消除了。上海自然要和北京競爭,但北京不這麽看,不管哪裏好了,都是它北京的,不是嗎?如何讓所有的TCP連接公平共享全部的互聯網帶寬,是TCP擁塞控制算法的根本!註意兩個關鍵點,其一,公平地共享,其二,盡可能全部的帶寬。
這個問題是一個世界難題,沒有進程調度器那麽簡單!
進程調度器是作用於一個CPU的,或者簡單點說,作用於一臺機器。這臺機器就在你的手上,你,也就是調度器的設計者完全可以看清楚當前機器裏發生的一切,一切不公平癥狀,一切浪費現象可以讓設計者盡收眼底,你可以強制性拿一個進程的資源給予另一個進程,你也可以殺死過於貪婪的進程...對於TCP而言,根本沒有一個可以站在全球互聯網往下看的高人,TCP擁塞控制是完全分布式的,每一個設計者都只能看到自己機器上的那一部分連接!
然而,TCP擁塞控制之所以如此難並不是什麽所謂分布式導致的,其實分布式一點也不難,難點在於TCP擁塞控制總是被誤解,所以說在設計算法的時候,稍不留神就會南轅北轍,本來是避免擁塞的,實際上是添堵的。
為什麽會被誤解?其實凱撒早就說過,人們總是看到自己希望看到的。這句話還有另一層意思,人們樂於把自己看到的局部當成所有。人們可以一眼看到一整機器的進程,所以設計出一個好的進程調度器是很容易的,所以CFS出現了。但是大家看不到所有的TCP連接,大家看到的只是自己的TCP連接,所以大家只能臆測,我好,你也好。至於算法是否添堵,可能完全不是出於惡意,而完全是目光的短淺和格局之不高導致的。
一個正確的,且好的TCP擁塞控制算法應該是顧及所有的連接的,如果TCP不夠快,那就應該讓所有TCP都提速,這點體現了帶寬利用率的提高;如果TCP已經足夠快,那任何連接都不能更快,這點體現了公平性。換成人話非常簡單,如果你覺得開車走省道慢,那就上高速,如果你已經在高速公路上,請不要變道超車。
多麽簡單的道理,可還是能看到道路上變道超車的,我可能表達有問題,是所有的司機都在玩變道超車,如果讓這些人來設計TCP擁塞控制算法,會好到哪裏去呢?不幸的是,世界上TCP單邊加速玩的最火的那批人,和這批中國好司機是同一批人,無論什麽資源,唯一的目標除了搶,還是搶。
其實,我並非一個道德說教者,說什麽人人為我,我為人人的算法才是一個好的算法,說的就好像我自己做到了似的...
我是被兩位大師罵了才知錯就改了,其實我也走火入魔過...
前一段時間吧,我修改了一個擁塞算法,呈給一位大師評解,姑且叫大師1吧,值得"炫耀"的就是我這個算法非常快,甚至比BBR還要快,但是被惡損了一頓,我的算法“競賽肯定第一”,但是卻“不負責任”...這種是毀人品的算法。後來,我試著讓兩個或者多個運行同一個算法的流一起傳輸數據,果然...一些流會瞬間把剩余的流帶寬壓榨到0!連敵友都不分了,簡直就是流氓算法啊!這個算法從此也就閱後即焚了,完全不可用。
...
如果這還不算,那麽另一位大師2則徹底讓我覺得自己根本就狗屁都不懂。
這位大師在國外,跟我有時差,且能讀中文但不寫中文,我與之相反,我是能讀英文但寫起來費勁,所以只能郵件交流。主題還是擁塞控制,我由於急功近利只是問了“怎麽讓TCP數據發送速度更快”這樣的問題,答案很簡單,忽略擁塞控制並補償性重傳即可,然後我就寫了一個“忽略擁塞控制的擁塞控制算法”,並且挑釁般的作為回應。然後的郵件裏就出現了fxxk詞匯,還有suck...說我根本就不懂基本的原則,並力勸我辭去工作回家仔細學習和思考。我都快哭了。
...........
大師2的教導在大師1之前,但是大師1給了我具體怎麽做的方向和方法,我除了發自內心的感謝之外,能做的就是寫一些“抨擊TCP擁塞控制算法”的文章來把人人為我,我為人人的基督教理念傳遞給更多的人。出於對兩位大師以及各路朋友的尊重,我不會貼出與之相關的代碼,郵件原文以及聊天記錄,消化加工後的理念,由我這裏直接始發。
BBR
BBR和當年的CFS一樣,這個我已經說過了。但是BBR目前仍處在比較初級的階段,起初呢,我認為它的問題在於:
1.收斂太慢,即不會即時降速降窗,而是要在幾個RTT內完成;
2.向上探測太遲。難道問題1是對這個的補償也說不準;
3.大BDP緩存下的搶占性有待商榷;
4.BBR依托的SDN基礎設施...
...
可以看到,這種最初的領悟體現了我個人多麽深厚的技術功底。然而後來,經大師指點,我才發現,原來BBR的最大問題在於,它引入的新擁塞控制框架很容易被誤用,具體的請參見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頁,再之前的一個小時,我看了一些關於道路規劃的東西,主要在令人不安的電腦上...現在,本來我想睡一覺,然而睡不著,就想去登高望遠,只可惜旁邊的山都太矮小了...自從甘孜歸來,深圳的山就成小土堆了...實際一點,去買菜,做飯才是解決之道,做什麽飯呢?哈哈,重慶帶來的老火鍋!
----我希望你能看到這篇文章。
再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow
讓人很容易誤解的TCP擁塞控制算法