當前位置:
首頁 > 科技 > 使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節

周六,由於要趕一個月底的Deadline,因此選擇了在家VPN加班,大半夜就爬起來跑用例,抓數據……自然也就沒有時間寫文章和外出耍了,不過利用周日的午夜時間(不要問我為什麼可以連續24小時不睡覺,因為我覺得吃飯睡覺是負擔),我決定把工作上的事情先放下,還是要把每周至少一文補上,這已經成了習慣。由於上周實在太忙亂,所以自然根本沒有更多的時間去思考一些「與工作無關且深入」的東西,我指的與工作無關並非意味著與IT,與互聯網無關,只是意味著不是目前我在做的。比如在兩年前,VPN,PKI這些是與工作有關的,而現在就成了與工作無關的,古代希臘羅馬史一直都是與工作無關的,直到我進了羅馬歷史研究相關的領域去領薪資,直白點說,老闆不為之給我支付薪水的,都算是工作無關的東西。玩轉與思考這些東西是比較放得開的,不需要對誰負責,沒有壓力,沒有KPI,沒有Deadline,完全自由的心態對待之,說不定真的很容易獲得真知。


我認識一個草根鼓手朋友,玩轉爵士鼓的水準遠高於那些所謂的專業鼓手,自然帶有一種俠客之風傳道授業解惑,鼓槌隨心所欲地揮舞在他自己的心中,沒有任何負擔和障礙,任何的節奏都可以一氣呵成,從來不打重複鼓點,那叫一個帥!然而他並非專業考級出來的,是拜師出來後自己摸索的。


要興趣去自然揮灑,而不是迫於壓力去應對。


我也是鼓手,但我打的不是爵士鼓,我是鼓噪者,技術的鼓噪者。本文與TCP BBR演算法相關。


0. 說明

BBR熱了一段時間後終於回歸了理性,這顯然要比過熱地炒作要好很多。這顯然也是我所期望的。


本文的內容主要解釋一些關於BBR的細節問題。這些問題一般人可能不會關注,但是針對這些問題仔細思考的話,會得到很多有用的東西。在解釋這些問題時,我依然傾向於使用圖解的方式,但這一次我不再使用Wireshark的tcptrace圖了,而是使用時序圖的方式,因為這種時序圖既然能夠令人一目了然地解釋TCP三次握手,四次分手,TIME-WAIT等,那它自然也能解釋更複雜的機制,比如說擁塞控制。


1. 延遲ACK以及ACK丟失並不會影響TCP的傳輸速率


在大的時間尺度上看,延遲ACK以及ACK丟失並不會對速率造成任何影響,比如一個文件4個TCP段正好發完,即便前面幾個ACK全部丟失,只有最後一個到達,那它的傳輸總時間也是不變的。


但是在細微的時間段內,由於延遲ACK或者ACK丟失帶來的時間偏差卻是不可忽略的。


首先我們再次看一下BBR是如何測量即時速率的。測量即時速率需要做一個除法,分子是一段時間內成功到達對端的數據包總量,分母就是這段時間。BBR會在每收到一次ACK的時候測量一次即時速率。計算需要的數據分別在數據傳輸和數據被ACK的時候採樣。很顯然,我們可以想當然地拍腦袋得出一個演算法:


設數據包x發出的時間為t1,數據包x被應答的時間為t2,則在數據包x被應答時採集的即時速率為:


Rate=(從x被發出到x被應答之間一共ACK以及SACK了多少個數據包)/(t2-t1)


但是這會造成什麼問題呢?這會造成誤差。如下圖所示:

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節


BBR如果依賴這種即時的速率測量機制來運作的話,在ACK丟失或者延遲ACK的情況下會造成測量值偏高。舉一個簡單的例子:

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節



那麼,BBR是如何做到不引入這種誤差從而精確測量即時速率的呢?很簡單,將t1改成至數據包x發出時為止,最後一個(S)ACK收到的時間即可。


詳情請參考內核源碼的net/ipv4/tcp_rate.c文件,原理非常簡單。


所以說,BBR的速率測量值並不受延遲ACK,ACK丟失的影響,其測量方法是妥當的。之所以上面給出一個錯誤的方法,是想展示一下什麼樣的做法是不妥當的,以及容易引起質疑的點在哪裡。


結論很明確,延遲ACK,ACK丟失,並不影響BBR速率的採集值。


接下來談第二個問題,關於BBR的擁塞窗口大小的問題。


2. 為什麼BBR要把計算出來的BDP乘以2作為擁塞窗口值?

這個問題可以換一種問法,即BBR的bbr_cwnd_gain值如何解釋:


我們知道,BBR將Pacing Rate作為第一控制要素,按照計算得到的Pacing Rate平緩地發送數據包即可,既然是這樣,擁塞窗口的存在還有何意義呢?


BBR的擁塞窗口控制已經退化到了規定一個限額,它主要是為了灌滿管道,解決由於ACK丟失導致的無包可發的問題。


我先來闡述問題。


BBR第一次把速率控制計算和實際的傳輸相分離,又一個典型的控制面與數據面相分離的案例。也就是說,BBR核心模塊計算出一個速率,然後就把數據包扔給Pacing發送引擎模塊(當前的實現是FQ,我自己也實現了一個),具體何時發送由Pacing發送引擎來控制,二者之間通過一個發送緩衝區來交互,具體結構如下圖:

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節



可見,擁塞窗口控制的是「到底扔多少數據到發送緩衝區合適」的。接下來的問題顯然就是,擁塞窗口到底是多少合適呢?


雖然BBR分離了控制邏輯和數據發送邏輯,但是TCP的一切都是ACK時鐘驅動的,如果ACK該來的時候沒有來,比如說丟了,比如延遲了,那麼就會影響BBR整個核心的運作,進而影響Pacing發送引擎的數據發送動作,BBR要做的是,即便沒有ACK來驅動,也可以自行發送本該發送的數據包,因此Pacing發送引擎的發送緩衝區的意義重要,說白了就是,發送緩衝區里一定要有足夠的數據包才行,就算ACK沒有來,引擎還是有包可發的。


下面來展示一幅圖:

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節



如果這個圖有不解之處,像往常一樣,大家一起討論,但總的來講,我覺得問題不大,所以說才會基於上圖產生了下圖:

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節



該圖示中,我把TCP層的BBR核心模塊和FQ的發送模塊都畫了出來,這樣我們可以清晰看出擁塞窗口的作用。實際上,BBR核心模塊按照擁塞窗口即inflight的限制,將N個數據包注入到Pacing發送引擎的發送緩衝區中,這些包會在這個緩衝區內部排隊,最終在輪到自己的時候被發送出去。由於這個緩衝區里有足夠的數據包,所以即使是ACK丟失了多個,或者接收端有LRO導致ACK被大面積聚集且延遲,發送緩衝區裡面的數據包也足夠發送一陣子了。


維護這麼一個發送緩衝區的好處是在緩衝區不溢出(為什麼不溢出?那是算出來的,正好兩倍)的前提下時時刻刻有包可發,然而代價也是有的,就是增加了RTT,因為在發送緩衝區里排隊的時間也要被算在RTT裡面的。不過這無所謂,這並不影響性能,數據包不管是在TCP層的發送隊列里,還是在FQ的隊列里,最終都是要發出去的。值得注意的是,本地的FQ隊列和中間節點的隊列性質完全不同,本地的隊列是獨佔的,主動的,而中間節點隊列是共享的,被動的,所以這裡並沒有因為RTT的增加而損失性能。這就好比你有一張銀行卡專門用來還房貸,由於利息的浮動,所有每月還款金額不同,為了不欠款,你每個月總是要存進足額的錢進去,一般要遠多於平均的還貸額度才最保險,但這並不意味著你多存了錢這些錢就虧了,在還清貸款之前,存進去的錢早晚都是要還貸的。


3. 為什麼在探測最小RTT的時候最少要保持4個數據包


首先要注意的是,用1個包去探測最小RTT會更好,然而效率可能會更低;用5個包去探測最小RTT效率更好,但是可能會導致排隊,為什麼4個包不多也不少呢?


我嘗試用一個時序圖來說明問題:

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節



可見,4個包的窗口是合理的,infilght分別是:剛發出的包,已經到達接收端等待延遲應答的包,馬上到達的應答了2個包的ACK。一共4個,只有1個在鏈路上,另外1個在對端主機里,另外2個在ACK里。路上只有1個包,這絕對合理,如果一條路連1個包都容納不下了,那還玩個屎啊!


以上的論述,僅僅為了幫大家理解以下一段注釋的深意:


4. 用時序圖總覽一下BBR的Startup/Drain/ProbeBW階段


我以下面的時序圖展示一下BBR的流程:

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節



5. Startup階段擁塞窗口計算的滯後性


我們知道,BBR裡面擁塞窗口已經不再是主控因素,事實上它的名字應該改成「發送緩衝區限額」會比較合適了,為了方便起見,我仍然稱它為擁塞窗口,雖然它的含義已經改變。

在Startup階段,發送速率每收到一個ACK都會提高bbr_high_gain:


這個其實跟傳統擁塞演算法的「慢啟動」效果是類似的。


然而BBR計算擁塞窗口是用「當前採集到的速率」乘以「當前採集到的最小RTT」來計算的,這就造成了「當前發送窗口」和「當前已經提高的速率」之間的不匹配,所以,計算擁塞窗口的時候,gain因子也必須是bbr_high_gain,從而可以吸收掉速率的實際提升。


6. 由ACK通告的接收窗口還有意義嗎?


在以往的Reno/CUBIC年代,窗口的計算是根據既有的固定數學公式算出來的,完全僅僅由ACK來驅動,無視事實上的傳輸速率,所以彼一時的擁塞窗口僅僅可以代表網路的情況,即便如此,這種網路狀態的結論也是猜的。


到了BBR時代,主動測量傳輸速率,將網路處理能力和主機處理能力合二為一,如果網路瓶頸帶寬為10,而主機處理能力為8,那麼顯然採集到的帶寬不會大於8!反之亦然。如果BBR測量的即時速率很準確的話,我想通告窗口就完全沒有意義了,通告的接收窗口會被忠實地反映在發送端採集到的即時速率里。BBR只是重構了擁塞控制演算法,但還沒有重構TCP處理核心,我想BBR可以重構之!


7. BBR在計算擁塞窗口時其它的關鍵點


1) 延遲ACK的影響


計算擁塞窗口的時候,會將目標擁塞窗口進行一下調整:


此處向上取偶數就是為了平滑最後一個延遲ACK的影響,如果最後一個延遲ACK該來的沒來,那麼這個向上取偶數可以為之補上。

2) Offload的影響

使用TCP時序圖解釋BBR擁塞控制演算法的幾個細節



8. 關於我的Pacing發送引擎


我在今年1月份寫了一版和TCP BBR相結合的Pacing發送引擎,以消除FQ對RTT測量值(增加排隊延遲)的影響,個人覺得我這個要比FQ那個好很多,畢竟是原湯化原食的做法吧。


直接在TCP層做Pacing其實並不那麼Cheap,因為三十多年來,TCP並沒有特別嚴重的Buffer bloat問題,所以TCP的核心框架實現幾乎都是突發數據包的,完全靠ACK來驅動發送,這個TCP核心框架比較類似一個令牌桶,而不是一個整型器!


令牌桶:決定能不能發送;


整型器:決定如何發送數據,是突發還是Pacing發送;


可見這兩者是完全不同的機制!要想把一個改成另一個,這個重構的工作量是可想而知。因此我實現的那個TCP Pacing只是一個簡版。真正要做得好的話,勢必要重構TCP發送隊列的操作策略,比如出隊,入隊,調度策略。


現階段,我們能使用的一個穩定版本的Pacing替代方案就是FQ,我們看看Linux的注釋怎麼說:

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

從 0到1 開啟智能化硬體開發
實習申請被Apple Music拒了之後,我重新設計它
Blockchain DB,區塊鏈資料庫
與2000位開發者共約CCTC 2017

TAG:CSDN |

您可能感興趣

BIOS設置選項詳細解釋——CPU核心篇
BIOS設置選項詳細解釋——電壓篇
小科普|BIOS設置選項詳細解釋①——CPU核心篇
BIOS設置選項詳細解釋——內存篇
BIOS設置選項詳細解釋——晶元組篇
BIOS設置選項詳細解釋——系統監視&系統啟動篇
小科普|BIOS設置選項詳細解釋③——電壓篇
詳細解釋路由器三種無線連接方式,WISP、Client+AP、WDS的區別
媽媽聽我解釋!《BIKINI WARRIORS》追加角色公開
《BEATLESS》導演解釋為啥很少談作品
用信鴿來解釋 HTTPS
MOMOLAND靠唱片銷售分數得MCD一位?經紀公司解釋網友卻另有想法
對BLACKPINK舞台中被請下台,主辦方終於道歉,解釋原因是這樣的
小科普|BIOS設置選項詳細解釋②——內存篇
從語義上理解卷積核行為,UCLA朱松純等人使用決策樹量化解釋CNN
我嘗試著向不懂潮流的朋友解釋 INNERSECT
CCP解釋退出VR原因,曾預計VR是現在兩到三倍規模
作為頂級旗艦,OPPO find x卻沒有無線充電和NFC,官方這樣解釋
小科普|BIOS設置選項詳細解釋④——晶元組篇
Cell Rep:解釋為何CRISPR-Cas9存在脫靶效應