BBR 原理導讀

最近在排查網絡問題時,發現在服務器上部署了 Linux 4.9 的 TCP BBR 擁塞控制算法以後,訪問速度得到 了成倍的提示,頓時覺得⼗分神奇,在⽹上查詢了 BBR 相關資料,閱讀了 BBR 的論⽂,下⾯基於該論⽂向 ⼤家簡要分析⼀下 BBR 的來⻰去脈。

什麼是 BBR

2016 年底 google 的開發者 Neal Cardwell 等 5 個⼤⽜在 acmqueue 上發表了論⽂ BBR: Congestion- Based Congestion Control,提出了 TCP 擁塞控制的 BBR 算法。BBR 即 Bottleneck Bandwidth and Round-trip propagation time,正如其名,它是⼀種基於瓶頸帶寬和往返傳播時間的擁塞控制算法。

背景

基於丟包的擁塞控制算法的缺陷

在 tcp 擁塞控制算法提出的 20 世紀 80 年代,直接把丟包等價於發⽣了擁塞,需要降低發送 速率。受限於硬件的發展⽔平和⽹絡普及程度,這在過去的很⻓⼀段時間都是⼗分適⽤的。然⽽ 30 多年 過去了,⽹絡的帶寬從⼏ Mbps 已經發展到了⼏ Gbps,⽹絡上的⽹卡、交換機和路由器的內存也從⼏ KB 發展到了⼏ GB。並且⽹絡的複雜程度也原超當年,各種跨洋跨⼤洲的通信鏈路以及⽆線⽹絡使得⽹ 絡丟包和⽹絡擁塞的關係越來越稀薄。在實際情況中,⾼速⼴域⽹內的傳輸錯誤丟包是不能忽略的,特 別是在⽆線⽹絡的情況下,整個鏈路的不穩定性導致的丟包更是⾮常常⻅。如果簡單的認爲丟包就是擁 塞所引起,從⽽降低⼀半的速率,將會導致⽹絡吞吐變低。 

⽹絡中的各種設備基本都有⾃⼰的緩存,基於丟包的擁塞控制算法⾸先會填 滿⽹絡中的緩存,當緩存填滿以後出現了丟包纔開始降低發送速率。如果⽹絡瓶頸的緩存⽐較⼤時,這 278 就可能造成極⼤的延時。要解決上⾯的問題,就需要另外⼀種思路,不是基於丟包來估計⽹絡發⽣了擁堵。

原理

tcp 擁塞控制的初衷是爲了在保證通信質量的前提下儘可能⾼的利⽤通信鏈路的帶寬。⼀個 tcp 鏈接就如同 ⼀條條管道,評價⼀條 tcp 鏈路的傳輸性能主要依靠 2 個參數: RTprop (round-trip propagation time) 往 返傳播時間和 BtlBw (bottleneck bandwidth) 瓶頸帶寬,就如同現實管道中的管道⻓度和最⼩直徑。

當⽹絡中數據包不多,還沒有填滿瓶頸鍊路的管道時,RTprop 決定着鏈路的性能。隨着投遞率的增加,往 返時延不發⽣變化。在 1979 Leonard Kleinrock 證明了,當數據包剛好填滿管道時,即滿⾜最⼤帶寬 BtlBw 和最⼩時延 RTprop,⽆論是單獨鏈接還是整個⽹絡來說是最優⼯作點。定義帶寬時延積 BDP=BtlBw × RTprop,則在最優點⽹絡中的數據包數量 = BDP。繼續增加⽹絡中的數據包,超出 BDP 的 數據包會佔⽤ buffer,達到瓶頸帶寬的⽹絡的投遞率不再發射變化,RTT 會增加。繼續增加數據包, buffer 會被填滿從⽽發⽣丟包。故在 BDP 線的右側,⽹絡擁塞持續作⽤。過去基於丟包的擁塞控制算法⼯ 作在 bandwidth-limited 區域的右側邊界,將瓶頸鍊路管道填滿後繼續填充 buffer,直到 buffer 填滿發⽣ 丟包,擁塞控制算法發現丟包,將發送窗⼝減半後再線性增加。過去存儲器昂貴,buffer 的容量只⽐ BDP 稍⼤,增加的時延不明顯,隨着內存價格的下降導致 buffer 容量遠⼤於 BDP,增加的時延就很顯著了。

針對上述的問題,BBR 採⽤了完全不同的⽅案:既然丟包不能等同於擁塞,那就忽略丟包,通過觀測和量 化鏈路的瓶頸帶寬和往返時延來讓擁塞控制算法處理真正的⽹絡擁塞,從⽽儘可能的讓⽹絡傳輸達到 Kleinrock 所提出來的最優⼯作點。

然⽽另外⼀個問題隨之⽽來了,同樣在 20 世紀 80 年代,Jeffrey M. Jaffe 就證明了沒有什麼算法能同時計 算出這個最佳⼯作點。要測量最低延遲 (min RTT),就必須要排空緩存,⽹絡中的數據包越少越好,⽽此時 帶寬是較低的。要測量最⼤帶寬 (max BW),就要把鏈路瓶頸填滿,在 buffer 中有⼀定的數據包,⽽此時延 時⼜是較⾼的。

針對測不準的問題,BBR 算法採⽤的⽅案是,交替測量帶寬和延遲,⽤⼀段時間內的帶寬極⼤值和延遲極 ⼩值作爲估計值,動態更新測量值,最終控制發送速率,避免⽹絡擁塞。

實現

BBR 啓動以後主要分爲四個階段:

BBR 採⽤類似標準 TCP 的 slow start,指數的⽅式來探測⽹絡的帶寬,⽬的也 是儘可能快的佔滿管道,經過三次發現投遞率不再增⻓,說明管道被填滿,開始佔⽤ buffer。

指數降低發送速率,相當於是 startup 的逆過程,將多佔的 buffer 慢慢排空。

在之後,BBR 進⼊穩定⼯作狀態。BBR 會不斷的通過改變發送速率進⾏帶寬探測,先在 ⼀個 RTT 時間內增加發送速率探測最⼤帶寬,如果 RTT 沒有變化,後減⼩發送速率排空前⼀個 RTT 多發 出來地包,後⾯ 6 個週期使⽤更新後的估計帶寬發包

延遲探測階段,BBR 設定了 min RTT 的超時時間爲 10 秒,每過 10 秒,會進⼊⾮常短暫延 遲探測階段,爲了探測最⼩延遲,BBR 在這段時間內僅發送最少量的包。

在穩定⼯作的情況下,BBR 會交替的進⾏帶寬探測和延時探測,並且越 98% 時間都處於帶寬探測階段,帶 寬探測階段時定期嘗試增加發包速率,如果收到確認的速率也增加了,就進⼀步增加發包速率。下圖展示了在第 20s 時⽹絡帶寬增加⼀倍時⽹絡的⾏爲。向上的尖峯表明它增加發送速率來探測帶寬變化, 向下的尖峯表明它降低發送速率排空數據。如果帶寬不變,增加發送速率肯定會使 RTT 增加。如果帶寬增 加,則增加發包速率時 RTT 不變。這樣經過三個週期之後,估計的帶寬增加了 1.95 倍。284 ⽽在第 40s 時⽹絡帶寬減半,因爲發送速率不變,inflight(在途數據包) 增加,多出來的數據包占⽤了 buffer,RTT 會顯著增加,帶寬的估計是滑動窗⼝時間內的極⼤值,當之前的估計值超時之後,降低⼀半 後的有效帶寬就會變成新的估計帶寬從⽽減⼩發送速率,經過 4 秒後,BBR 逐漸收斂。

效果

我們回過頭再來看 BBR 要解決的 2 個問題

上圖可以看到,傳統的 TCP CUBIC 在隨着丟包率的增加性能急劇下降,在千分之⼀的丟包率情況下,系統 吞吐量就下降到⽹絡的百分之⼗,⽽ BBR 則在百分之五以下的丟包率的情況下,基本沒有性能損失。

上圖展示了在不同 buffer ⼤⼩的情況下,BBR 和 CUBIC 的延時表現。紅線爲傳統 TCP CUBIC,CUBIC 傾 向於填滿 buffer,這也導致延遲基本隨着 buffer 的增⼤線性增⻓,⽽延時過⻓可能直接導致系統建⽴連接 超時。⽽ BBR 基本保持發送隊列爲最⼩,隨着 buffer 的增加⽹絡延遲基本不變。所以 BBR 能在存在⼀定丟包率的的⽹絡環境中充分利⽤帶寬,⼗分的適合在跨區域的⾼延遲⾼速⽹絡。當 然 BBR 也不是萬能的,許多測試和實際應⽤也發現了 BBR 存在在⽹絡狀況變化較⼤的情況下測不準導致⼤ 量丟包,交替測量導致波動較⼤,收斂較慢導致的公平問題等。Google 也在持續優化 BBR 算法,在 2018 年 公佈的 BBR 2.0 研究進展中就包含了: 

參考⽂獻 

[1] Neal Cardwell. "TCP BBR congestion control comes to GCP – your Internet just got faster" 

[2] Neal Cardwell, et al. "BBR: Congestion-Based Congestion Control." 

[3] Yuchung Cheng, Neal Cardwell. "Making Linux TCP Fast" 

[4] Neal Cardwell. "BBR Congestion Control Work at Google IETF 102 Update"

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/j10wc2TZG9ddbio7UeYUaQ