本文首發於 面試熱點|淺談TCP/IP傳輸層TCP BBR算法
微信公衆號 後端技術指南針
這是TCP/IP協議棧系列的第三篇文章,以前的一篇面試熱點|理解TCP/IP傳輸層擁塞控制算法講述了傳統的擁塞控制算法基本原理,今天一塊兒來學習下最新Linux內核中增長的擁塞控制算法:TCP BBR算法。html
鑑於TCP擁塞控制算法背後有一套複雜的數學理論和控制策略,所以本文也只能是淺談,經過本文你將瞭解到如下內容(舒適提示:文章較長鬚要一些耐心,也能夠先收藏再閱讀):面試
大約在1988年以前TCP/IP是沒有擁塞控制的,可是隨着網絡接入規模的發展以前僅有的端到端窗口控制已經沒法知足要求,在1986年引起大規模網絡癱瘓,此時就要提到一個重量級人物:Van Jacobson範·雅各布森。算法
這位力挽狂瀾的人物入選了計算機名人堂Internet Hall of Fame,Van Jacobson大神提出並設計實施了TCP/IP擁塞控制,解決了當時最大的問題,來簡單看下Van Jacobson的維基百科簡介(筆者作了部分刪減):後端
範·雅各布森Van Jacobson是目前做爲互聯網技術基礎的TCP/IP協議棧的主要起草者,他以其在網絡性能的提高和優化的開創性成就而聞名。
2006年8月,他加入了帕洛阿爾託研究中心擔任研究員,並在位於相鄰的施樂建築羣的Packet Design公司擔任首席科學家。在此以前,他曾是思科系統公司首席科學家,並在位於勞倫斯伯克利國家實驗室的網絡研究小組任領導者。
範·雅各布森由於在提升IP網絡性能提高和優化所做的工做而爲人們所知,1988到1989年間,他從新設計了TCP/IP的流控制算法(Jacobson算法),他因設計了RFC 1144中的TCP/IP頭壓縮協議即範·雅各布森TCP/IP頭壓縮協議而廣爲人知。此外他也曾與他人合做設計了一些被普遍使用的網絡診斷工具,如traceroute,pathchar以及tcpdump 。
範·雅各布森於2012年4月入選第一批計算機名人堂,計算機名人堂簡介: www.internethalloffame.org/inductees/v…
如圖爲Van Jacobson計算機名人堂的簡介:緩存
筆者找了Van Jacobson和Michael J. Karels在1988年11月發佈的關於擁塞避免和控制的論文,總計25頁,感興趣的讀者能夠查閱:安全
ee.lbl.gov/papers/cong…
咱們經常使用的tracetoute和tcpdump也是van-jacobson大神的傑做,做爲互聯網時代的受益者不禁得對這些互聯網發展早期作出巨大貢獻的開拓者、創新者、變革者心生讚歎和敬意。服務器
看到一篇文章說到TCP 傳輸層擁塞控制算法並非簡單的計算機網絡的概念,也屬於控制論範疇,感受這個觀點很道理。微信
TCP擁塞控制算法的目的能夠簡單歸納爲:公平競爭、充分利用網絡帶寬、下降網絡延時、優化用戶體驗,然而就目前而言要實現這些目標就不免有權衡和取捨。markdown
可是如今的網絡通訊基礎設施水平一直在飛速提升,相信在將來的某個時間點這些目標均可以達到,小孩子才選擇,咱們大人全都要!網絡
在理解擁塞控制算法以前咱們須要明確一個核心的思想:聞道有前後 術業有專攻,筆者以爲這是一個很是重要的共識問題,把A踩在泥土裏,把B吹捧到天上去,都不是很好的作法。
實際的網絡環境十分複雜而且變化很快,並無哪一個擁塞控制算法能夠所有搞定,每一種算法都有本身的特定和適用領域,每種算法都是對幾個關鍵點的權衡,在沒法兼得的條件下有的算法選擇帶寬利用率,有的算法選擇通訊延時等等。
在明確這個共識問題以後,咱們對待各個擁塞控制算法的態度要平和一些,不要偏激地認爲誰就是最好,幾十年前的網絡情況和如今是大相徑庭的,咱們永遠都是站在巨人的肩膀之上的,這也是科學和文明進步的推進力。
傳統擁塞控制算法並非一蹴而就的,複雜的網絡環境和用戶的高要求推進着擁塞控制算法的優化和迭代,咱們看下基於丟包策略的傳統擁塞控制算法的幾個迭代版本,如圖所示:
與此同時還有一類算法是基於RTT延時策略來進行控制的,可是這類算法在發包速率上可能不夠激進,競爭性能不如其餘算法,所以在共享網絡帶寬時有失公平性,可是算法速率曲線倒是很平滑,咱們暫且把這類算法當作君子吧!
其中比較有名的Vegas算法是大約在1995年由亞利桑那大學的研究人員拉里·彼得森和勞倫斯·布拉科夫提出,這個新的TCP擁塞算法之內華達州最大的城市拉斯維加斯命名,後成爲TCP Vegas算法。
關於基於RTT的TCP Vegas算法的詳細介紹能夠查閱文檔:
www.cs.cmu.edu/~srini/15-7…
文檔對Vegas算法和New Reno作了一些對比,咱們從直觀圖形上能夠看到Vegas算法更加平滑,相反New Reno則表現除了較大的波動呈鋸齒狀,如圖所示:
實際上還有更細粒度的分類,因爲不是今天的重點,就再也不深刻展開了,當前使用的擁塞控制算法仍是基於丟包Loss-Based做爲主流。
咱們知道在網絡鏈路中鏈接的數量是動態變化且數量巨大的,每一條鏈接都面臨着一個黑盒子式的網絡環境,這並不像咱們平時出行時看看地圖就知道哪裏堵了,爲了維護一個好的網絡環境,每一條鏈接都須要遵照一些約定。
若是鏈接端都無所顧忌地發生數據包,那麼網絡鏈路很快就到了瓶頸了,數據通訊徹底沒法保障,因此要到達一個穩定高效的網絡環境仍是須要費很大心思的,這其中有兩個重要的概念:公平性和收斂性。
說來慚愧筆者在網絡上找了不少資料去理解TCP擁塞控制的公平性和收斂性,可是仍然沒有得到一個很好的權威解釋,因此只能結合一些資料和自身的理解去闡述所謂的公平性和收斂性。
筆者認爲公平性是相對於網絡鏈路中的全部鏈接而言的,這些共享鏈路的鏈接啓動和結束的時間不一樣,在實際的交互過程當中每條鏈接佔有帶寬的機會是均等的,而且因爲帶寬限制鏈接雙方通訊的數據量是動態調整而且近似收斂於某個值,也就是呈現一個鋸齒狀或者更加平滑的波動曲線,對於基於丟包的擁塞控制算法而言AIMD線性增乘性減策略起了關鍵控制做用。
接下來咱們來重點看下AIMD特性,先來貼一張經典的圖,直觀看AIMD的過程:
看看維基百科對於AIMD的定義:
The additive-increase/multiplicative-decrease(AIMD) algorithm is a feedback control algorithm best known for its use in TCP congestion control.
AIMD combines linear growth of the congestion window with an exponential reduction when congestion is detected.
Multiple flows using AIMD congestion control will eventually converge to use equal amounts of a shared link.
The related schemes of multiplicative-increase/multiplicative-decrease (MIMD) and additive-increase/additive-decrease (AIAD) do not reach stability.
簡單翻譯一下:線性增長乘性減小算法是一個反饋控制算法,因其在TCP擁塞控制中的使用而廣爲人知,AIMD將線性增長擁塞窗口和擁塞時乘性減小窗口相結合,基於AIMD的多個鏈接理想狀態下會達到最終收斂,共享相同數量的網絡帶寬,與其相關的乘性增乘性減MIMD策略和增性加增性減小AIAD都沒法保證穩定性。
AIMD相比MIMD和AIAD在鏈接進入擁塞避免階段使用試探線性加策略而不是乘性加策略更加安全,在探測丟包時則大幅度乘性減小到1/2這樣對於緩解擁塞會有比較好的效果更加快速,相反若是探測到丟包時採用線性減小AD可能擁塞持續的時間會更長,整體來講AIMD算是一個比較簡單實用的工程版本的反饋控制,也具有可工程收斂性,於是被普遍實用。
時間拉回20多年前,在互聯網早期幾乎全部的設備都是經過有線網絡進行鏈接通訊的,這也是擁塞控制在設計以後一直都起到不錯做用的重要因素,有線鏈接的網絡穩定性比較好,所以把丟包做爲網絡擁堵的一個特徵也很正常。
再拉回到如今,從2010年以後移動互聯網蓬勃發展,移動終端的持有量已經能夠稱爲海量,無線網絡的引入讓網絡環境變得更加複雜,所以不穩定丟包變得更加頻繁,可是這時的丟包就不必定是網絡擁堵形成的了,由於整個數據包通過多重路由、交換機、基站等基礎通訊設備每一個環節均可能發生異常。
在弱網環境下,尤爲是移動互聯網中以前的基於AIMD的擁塞控制策略可能會因爲丟包的出現而大幅下降網絡吞吐量,從而對網絡帶寬的利用率也大大降低,這時咱們採用更加激進的控制策略,或許能夠得到更好的效果和用戶體驗。
惡意丟包的狀況下,基於AIMD的擁塞控制確實就至關於被限速了,由於AIMD確實有些保守謹慎了,這個其實也很好理解的哈。
咱們都知道在移動網絡環境下是由終端以無線形式和附近的基站交互數據,以後數據傳輸至核心網,最後落到具體的服務器所在的有線網絡,其中最後一千米的區域屬於高延時場景,有線網絡屬於低延時高帶寬場景。
在國外有相關實驗證實弱網環境下RTT的變化對於使用傳統擁塞控制算法下網絡吞吐量的影響,數據和曲線如圖所示:
實驗含義:RTT的增大影響了好比CUBIC這類擁塞控制算法的慢啓動等階段,咱們知道慢啓動階段每通過1個RTT週期擁塞窗口cwnd將加倍,可是更大的RTT就意味着發送方以很低的速率發送數據,更多的時間是空閒的,發包的加速度極大將低了,因此整個吞吐量就降低很明顯。
看下實驗者的原文表述:
The delay before acknowledgment packets are received (= latency) will have an impact on how fast the TCP congestion window increases (hence the throughput).
When latency is high, it means that the sender spends more time idle (not sending any new packets), which reduces how fast throughput grows.
BBR算法是個主動的閉環反饋系統,通俗來講就是根據帶寬和RTT延時來不斷動態探索尋找合適的發送速率和發送量。
看下維基百科對BBR算法的說明和資料:
相關文獻: queue.acm.org/detail.cfm?…
TCP BBR(Bottleneck Bandwidth and Round-trip propagation time)是由Google設計,並於2016年發佈的擁塞算法,以往大部分擁塞算法是基於丟包來做爲下降傳輸速率的信號,而BBR基於模型主動探測。
該算法使用網絡最近出站數據分組當時的最大帶寬和往返時間來建立網絡的顯式模型。數據包傳輸的每一個累積或選擇性確認用於生成記錄在數據包傳輸過程和確認返回期間的時間內所傳送數據量的採樣率。
該算法認爲隨着網絡接口控制器逐漸進入千兆速度時,分組丟失不該該被認爲是識別擁塞的主要決定因素,因此基於模型的擁塞控制算法能有更高的吞吐量和更低的延遲,能夠用BBR來替代其餘流行的擁塞算法例如CUBIC。Google在YouTube上應用該算法,將全球平均的YouTube網絡吞吐量提升了4%,在一些國家超過了14%。BBR以後移植入Linux內核4.9版本,而且對於QUIC可用。
基於丟包反饋屬於被動式機制,根源在於這些擁塞控制算法依據是否出現丟包事件來判斷網絡擁塞作減窗調整,這樣就可能會出現一些問題:
前面咱們提到了一些Loss-Based算法存在的問題,TCP BBR算法是一種主動式機制,簡單來講BBR算法再也不基於丟包判斷而且也再也不使用AIMD線性增乘性減策略來維護擁塞窗口,而是分別採樣估計極大帶寬和極小延時,並用兩者乘積做爲發送窗口,而且BBR引入了Pacing Rate限制數據發送速率,配合cwnd使用來下降衝擊。
BBR算法的一些思想在以前的基於延時的擁塞控制算法中也有出現,其中必有有名的是TCP WestWood算法。
TCP Westwood改良自New Reno,不一樣於以往其餘擁塞控制算法使用丟失來測量,其經過對確認包測量來肯定一個合適的發送速度,並以此調整擁塞窗口和慢啓動閾值。其改良了慢啓動階段算法爲敏捷探測和設計了一種持續探測擁塞窗口的方法來控制進入敏捷探測,使連接儘量地使用更多的帶寬。
TCP WestWood算法也是基於帶寬和延時乘積進行設計的,可是帶寬和延時兩個指標沒法同時測量,由於這兩個值是有些矛盾的極值,要測量最大帶寬就要發送最大的數據量可是此時的RTT可能會很大,若是要測量最小的RTT那麼久意味着數據量很是少最大帶寬就沒法得到。
TCP BBR算法採用交替採樣測量兩個指標,取一段時間內的帶寬極大值和延時極小值做爲估計值,具體的實現本文就不展開了。
前面提到了BBR算法核心是尋找BDP最優工做點,在相關論文中給出了一張組合的曲線圖,咱們一塊兒來看下:
1.曲線圖示說明:
這張圖是由兩個圖組合而成,目前是展現[數據發送速率vs網絡數據]和[RTTvs網絡數據]的關係,橫軸是網絡數據數量。
兩個縱軸從上到下分別爲RTT和發送速率,而且整個過程分爲了3個階段:應用限制階段、帶寬限制階段、緩衝區限制階段。
2.曲線過程說明:
3.一些見解
網上有一些資料都說起到了這張圖,其中的一些解釋也並不算很是清晰,結合這些資料和本身的認識,筆者認爲在網絡鏈路的緩存區沒有被使用時RTT爲最小延時MinRTT,在網絡鏈路緩衝區被佔滿時出現最大帶寬MaxBW(鏈路帶寬+鏈路緩存),可是此時的MaxBW和MinRTT並非最優的而是水位比較高的水平,有數據代表按照2ln2的增益計算此時爲3BDP,整個過程當中MinRTT和MaxBW是分開探測的,由於這兩者是不能同時被測量的。
BBR算法和CUBIC算法相似,也一樣有幾個過程:StartUp、Drain、Probe_BW、Probe_RTT,來看下這幾個狀態的遷移狀況:
To handle Internet link bandwidths spanning 12 orders of magnitude, Startup implements a binary search for BtlBw by using a gain of 2/ln2 to double the sending rate while delivery rate is increasing. This discovers BtlBw in log2BDP RTTs but creates up to 2BDP excess queue in the process.
咱們來看一下這四個過程的示意圖:
曲線說明:這兩個座標給出了10Mbps和40msRTT的網絡環境下CUBIC和BBR的一個對比過程,在上面的圖中藍色表示接收者,紅色表示CUBIC,綠色表示BBR,在下面的圖中給出了對應上圖過程當中的RTT波動狀況,紅色表明CUBIC,綠色表明BBR。
有一些文章認爲BBR有鮮明的特色,把擁塞控制算法分爲BBR以前和BBR以後,可見BBR仍是有必定影響,可是BBR算法也不是銀彈,不過能夠先看看BBR算法在谷歌推進下的一些應用效果,其中包括吞吐量、RTT、丟包率影響:
從圖中咱們能夠看到在YouTube應用BBR算法以後,就吞吐量廣泛有4%左右的提高,特別地在日本的提高達到14%,RTT的降低更爲明顯平均下降33%,其中IN(猜想是印度地區)達到50%以上,在丟包率測試中BBR並不想CUBIC那麼敏感,在丟包率達到5%是吞吐量纔開始明顯降低。
本文先回顧了以CUBIC爲表明傳統的擁塞控制算法,以後展開了對BBR算法的一些介紹。
網絡上關於BBR的文章不少,筆者也嘗試結合不少文章和外文資料進行理解和概括,可是因爲筆者工做經驗和水平所致上述文字中可能存在一些問題,對此表達歉意,而且不少細節也並未展開,因此只能當作是一次淺談了。
Linux Kernel 4.9 中的 BBR 算法與以前的 TCP 擁塞控制相比有什麼優點?