自 1980 年代網際網路崛起,到 1990 年代快速發展開始,就產生了 TCP 以及 UDP 的 IP 網路,1983年1月1日,ARPANet要求未來所有的網路傳輸都使用 IP 網路,統一了開放網路的規格。
網路通道就像是一條水管/水道,這條通道用來傳送資料,因為沒有即時調節流量的機制,TCP 透過接收端發送確認已經收到封包的 ACK,來判斷是否發送的速度太快,流量控制就是在控制資料發送端的發送速度。
BBR (Bottleneck Bandwidth and Round-trip propagation time) 演算法是 Google 在 2016 年提出的流量控制演算法,他透過有效頻寬偵測機制,並降低網路節點的 buffer 使用量,藉由減低重傳的效能消耗問題,提高頻寬使用率。
流量控制是在做什麼工作
把網路傳輸通道 TCP 想像為一條從山頂的水庫到目的地海洋的河流或水管,水庫有大量水資源,希望能運用水道以最短時間送到海洋,但是水庫並不知道這個水道有多寬,能以多少速度的水量放水。如果水放得太慢,無法享用水道的總流量,水放得太急,有可能會超過水道容量,而讓水漫出水道,造成淹水的情況。
流量控制,就是控制水庫放水速度的一個演算法,因為水道容水量的情況是隨時都在改變的,問題在於,並沒有即時回報的機制,可以隨時調節流量,另外,由於發送端貪婪的本性,他會希望盡可能完全佔用網路水道的所有容水量。
但總不能一直送一直送,也不管接收端有沒有收到資料吧。TCP 的機制是,在接收到收到封包時,會回覆一個 ACK 封包,確認已經收到了,透過 ACK 的偵測,就可以知道現在發送的速度,是不是已經超過了網路通道的容量,如果發生封包遺失的狀況時,發送端就知道要降低發送速度了。
雖然是開放網路,公平競爭,但實際上還是看誰最會搶佔網路資源,因此有些演算法強調搶佔的特性,會侵蝕掉使用其他演算法的 TCP 連線。
但從提供網路服務這一端來看,他希望所有來使用服務的使用者,可以公平地使用伺服器對外的網路通道,而且要盡可能減少因為 TCP 重傳的機制,造成無效的網路資源浪費,這時候,採用強調發送端公平使用網路的演算法,會比較有利。
因為網路通道本身不穩定的特性,如果中間有遇到無線網路時,這種情況會更嚴重,因此網路的路由器本身,通常都會加上 Buffer 的機制,能夠讓暫時無法發送的網路資料,存放在 Buffer 裡面,希望能藉此改善整體網路的效能。就像是水道中間,會加上一些滯洪池的機制,預防水量瞬間增加的問題。
然而這些 Buffer 卻因為 TCP 流量控制貪婪的本性,而被濫用,因為 TCP 希望自己能盡可能使用到網路的最大流量,所以也會盡可能將自己的封包,把路由器的 Buffer 塞滿,讓自己的速度更快,這也會造成 Bufferbloat 的問題。
網路上有許多網路節點,除了控制路由以外,有些節點還增加了 QoS(Quality of Service) 或是 Traffic Shaping 的機制,這也是基於剛剛提到的 Buffer 而提供的功能,因為有了 Buffer,路由器可以先將需要傳送的資料,放入不同等級的 Buffer 裡面,保留固定的傳送頻寬給具有高傳輸權限的網路封包。
BBR 演算法
BBR 演算法的細節,以這兩篇文章的說明比較清楚。
Linux Kernel 4.9 中的 BBR 算法與之前的 TCP 擁塞控制相比有什麼優勢?
要不然就要看原始發表的論文
BBR 解決問題的方案有兩點
- 因無法區分 congestion packet loss 及 error packet loss,BBR 考慮讓網路不產生 packet loss
- 因為把 buffer 塞滿可產生最大流量,但也會造成 RTT 降低,BBR 交替進行頻寬及 delay(RTT) 偵測
BBR 的四個狀態
- STARTUP 採用標準的 slow start 方式,指數增加發送速度,發現頻寬被佔滿時,就進入 DRAIN 的階段
- DRAIN 降低發送速度,將佔用的 buffer 排空
- PROBE_BW 改變發送速度進行頻寬偵測,在一個 RTT 內增加發送速度,如果 RTT 沒有改變,就降低發送速度,排空先前多送的封包,在六個 RTT 內使用這個發送速度
- PROBE_RTT 每經過 10s,如果沒有得到一個更低的延遲時間,就進入延遲偵測的階段,持續 200ms (或一個 RTT),這個階段固定發送 4 packets,偵測得到的最小 delay 時間作為最新的延遲時間
一些實測的結果
spotify: Smoother Streaming with BBR
這些是使用了 BBR 以後的測試說明,全部都是正面,效能有改善的結果。
Google 在宣傳 BBR 時,都說明只要修改 Server 的部分,讓 Server 以 BBR 演算法運作,原因在於,流量控制演算法著眼的重點,是大量資料的發生源,會產生大量資料,發送出來的地方。只要修改 Server 的原因是他們是針對 Youtube 這樣提供串流服務的 Server 套用 BBR,換句話說,BBR 適用於 Sender Side。
因為串流影音的特性,就是需要一條長時間運作且傳輸量穩定的網路通道,這正好符合了 BBR 提供的流量結果,因為沒有使用到 Router 的 buffer,也沒有大量的重傳封包抵銷了網路的效能。
如果是類似 Hangouts Meeting 這樣的多人雙向影音的應用,因為客戶端 client side 如果沒有使用 BBR,就可能會產生不穩定的個人影音發生源,即使 Server Side 提供了 BBR,也無法形成一個有良好體驗的網路環境。
並不是所有人都認為 BBR 是有用的,以 令人躁動一時且令人不安的TCP BBR算法 這篇文章提出的論點來看,BBR 適合用在速度比較穩定的網路通道上,因為增速快,降速慢的特性,並不適用於忽快忽慢的網路。
我個人的想法是,只要決定了網路通道,固定了網路通道,那麼大部分的情況,網路是穩定的,該文章提出的問題,說明的並不恰當,如果通道上有些路徑的頻寬比較小,這會讓整條網路通道都因為這個最小頻寬的一段路而降速。因為流量控制只會根據接收端的 ACK 來調節,沒辦法知道中間經過每一個網路節點的速度。
會發生問題的地方,應該是網路忽快忽慢的情況,因為變化太大,演算法無法很快地調節到最佳的傳送速度,但這應該是所有演算法都會遇到的問題,BBR 改善的結果已經有顯著的效果了。
如何啟用 BBR
How to Deploy Google BBR on CentOS 7
因為 BBR 已經有在 linux kernel 4.9+ 的版本上實作,在各 linux distribution 的安裝方式,都是安裝新的 kernel repo,將 kernel 更新到 4.9+。
然後在 /etc/sysctl.conf 增加這兩行設定
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
sysctl -p
用以下指令確認有沒有安裝成功
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
lsmod | grep bbr
BBR 可以終結流量控制的問題嗎?
這個 wiki 上的漫畫說明了現實的狀況,原本 BBR 的開發者,想要設計一個新的演算法,打敗既有12種 TCP Congestion Control 演算法,一統江湖,三年後,終於在 Linux 4.9 版 kernel 實現了 TCP BBR,但還是有某些缺陷,而現在變成了有 13 種 TCP Congestion Control 演算法。
References
Faster Networking with TCP BBR