寫本文的初衷一部分來自于工作,更多的來自于發(fā)現(xiàn)國內(nèi)幾乎還沒有中文版的關(guān)于TCP bbr算法的文章,我想搶個沙發(fā)。
本文的寫作方式可能稍有不同,之前很多關(guān)于OpenVPN,Netfilter,IP路由,TCP的文章中,我都是先羅列了問題,然后闡述如何解決這個問題。但是本文不同!本文的內(nèi)容來自于我十分厭惡的一個領(lǐng)域,其中又牽扯到我十分厭惡的一家公司-華夏創(chuàng)新(Appex),這些令我厭惡的東西讓我不得不放棄很多的東西。所以,我不會先說業(yè)界遇到了什么問題,而是直接步入主題,闡述bbr算法的組成。我十分討厭與人談?wù)撽P(guān)于TCP擁塞控制的話題,一方面是因為這個話題太過發(fā)散,任何人都可以說出自己的理由讓人信服自己的忽悠人的算法,另一方面,我覺得我接觸到的所有人當中并沒有人真的懂這些(當然,我也不懂!而且比那些人更加不懂?。晕覍幙苫ㄐr間在預研或者研發(fā)上,我也不想跟人瞎逼逼或者聽別人瞎逼逼。
隨便提出一個TCP擁塞算法,任何人都可以做到說它好,任何人也可以做到說它不好,因為沒人真的懂網(wǎng)絡(luò),所以聊這些是沒有意義的!TCP不是網(wǎng)絡(luò)范疇的技術(shù),它是控制論范疇的,TCP技術(shù)不屬于網(wǎng)絡(luò)技術(shù)!
我的觀點是,正確的做法只有一種,其它的都是錯誤的做法,都沒有意義!
國慶節(jié)前,我看到了bbr算法,發(fā)現(xiàn)它就是那個唯一正確的做法(可能有點夸張,但起碼它是一個通往正確道路的起點?。?,所以花了點時間研究了一下它,包括其patch的注釋,patch代碼,并親自移植了bbr patch到更低版本的內(nèi)核,在這個過程中,我也產(chǎn)生了一些想法,作為備忘,整理了一篇文章,記如下,多年以后,再看TCP bbr算法的資料時,我的記錄也算是中文社區(qū)少有的第一個吃螃蟹記錄了,也算夠了!
正文之前,給出本文的圖例:

使用BBR之前
我希望更多的人試用這個算法,并且與我共享測試結(jié)果,包括但不限于算法的帶寬利用率,搶占性等!特別是溫州皮鞋產(chǎn)老板!這個算法并不是我寫的,既然開源那就不應(yīng)該封閉于任何公司或者個人,所以我有權(quán)在這里就我知道的東西述說一二。
我深深地明白,我以下寫的這些有很多理解不周到的地方,我也深深的明白很多傳統(tǒng)學生出身的人不會告訴我那些疏漏,我指的是溫州老板那樣的人,因為他們幾乎都是在索取而不分享,如果他們發(fā)現(xiàn)了我的疏漏,他們會默默記上一筆,到頭來他們學會了我分享的東西,他們又改進了我的疏漏(但是并不告訴我?。?,他們又擁有自己獨立學會的那些東西(他們也不會告訴我?。?,所以,最終,他們?nèi)魏稳硕急任腋硬W且高明!然而不幸的是,這就是我的目標,我并不在乎那些人,我甚至不會在乎自己!
所以,趕緊試用bbr吧,趕緊改進吧,功勞是你的,虛無是我的!
BBR的組成
bbr算法實際上非常簡單,在實現(xiàn)上它由5部分組成:
1.即時速率的計算
計算一個即時的帶寬bw,該帶寬是bbr一切計算的基準,bbr將會根據(jù)當前的即時帶寬以及其所處的pipe狀態(tài)來計算pacing rate以及cwnd(見下文),后面我們會看到,這個即時帶寬計算方法的突破式改進是bbr之所以簡單且高效的根源。計算方案按照標量計算,不再關(guān)注數(shù)據(jù)的含義。在bbr運行過程中,系統(tǒng)會跟蹤當前為止最大的即時帶寬。
2.RTT的跟蹤
bbr之所以可以獲取非常高的帶寬利用率,是因為它可以非常安全且豪放地探測到帶寬的最大值以及rtt的最小值,這樣計算出來的BDP就是目前為止TCP管道的最大容量。bbr的目標就是達到這個最大的容量!這個目標最終驅(qū)動了cwnd的計算。在bbr運行過程中,系統(tǒng)會跟蹤當前為止最小RTT。
3.bbr pipe狀態(tài)機的維持
bbr算法根據(jù)互聯(lián)網(wǎng)的擁塞行為有針對性地定義了4中狀態(tài),即STARTUP,DRAIN,PROBE_BW,PROBE_RTT。bbr通過對上述計算的即時帶寬bw以及rtt的持續(xù)觀察,在這4個狀態(tài)之間自由切換,相比之前的所有擁塞控制算法,其革命性的改進在于bbr擁塞算法不再跟蹤系統(tǒng)的TCP擁塞狀態(tài)機,而旨在用統(tǒng)一的方式來應(yīng)對pacing rate和cwnd的計算,不管當前TCP是處在Open狀態(tài)還是處在Disorder狀態(tài),抑或已經(jīng)在Recovery狀態(tài),換句話說,bbr算法感覺不到丟包,它能看到的就是bw和rtt!
4.結(jié)果輸出-pacing rate和cwnd
首先必須要說一下,bbr的輸出并不僅僅是一個cwnd,更重要的是pacing rate。在傳統(tǒng)意義上,cwnd是TCP擁塞控制算法的唯一輸出,但是它僅僅規(guī)定了當前的TCP最多可以發(fā)送多少數(shù)據(jù),它并沒有規(guī)定怎么把這么多數(shù)據(jù)發(fā)出去,在Linux的實現(xiàn)中,如果發(fā)出去這么多數(shù)據(jù)呢?簡單而粗暴,突發(fā)!忽略接收端通告窗口的前提下,Linux會把cwnd一窗數(shù)據(jù)全部突發(fā)出去,而這往往會造成路由器的排隊,在深隊列的情況下,會測量出rtt劇烈地抖動。
bbr在計算cwnd的同時,還計算了一個與之適配的pacing rate,該pacing rate規(guī)定cwnd指示的一窗數(shù)據(jù)的數(shù)據(jù)包之間,以多大的時間間隔發(fā)送出去。
5.其它外部機制的利用-fq,rack等
bbr之所以可以高效地運行且如此簡單,是因為很多機制并不是它本身實現(xiàn)的,而是利用了外部的已有機制,比如下一節(jié)中將要闡述的它為什么在計算帶寬bw時能如此放心地將重傳數(shù)據(jù)也計算在內(nèi)。..
帶寬計算細節(jié)以及狀態(tài)機
1.即時帶寬的計算
bbr作為一個純粹的擁塞控制算法,完全忽略了系統(tǒng)層面的TCP狀態(tài),計算帶寬時它僅僅需要兩個值就夠了:
1)。應(yīng)答了多少數(shù)據(jù),記為delivered;
2)。應(yīng)答1)中的delivered這么多數(shù)據(jù)所用的時間,記為interval_us。
將上述二者相除,就能得到帶寬:
bw = delivered/interval_us
非常簡單!以上的計算完全是標量計算,只關(guān)注數(shù)據(jù)的大小,不關(guān)注數(shù)據(jù)的含義,比如delivered的采集中,bbr根本不管某一個應(yīng)答是重傳后的ACK確認的,正常ACK確認的,還是說SACK確認的。bbr只關(guān)心被應(yīng)答了多少!
這和TCP/IP網(wǎng)絡(luò)模型是一致的,因為在中間鏈路上,路由器交換機們也不會去管這些數(shù)據(jù)包是重傳的還是亂序的,然而擁塞也是在這些地方發(fā)生的,既然擁塞點都不關(guān)心數(shù)據(jù)的意義,TCP為什么要關(guān)注呢?反過來,我們看一下?lián)砣l(fā)生的原因,即數(shù)據(jù)量超過了路由器的帶寬限制,利用這一點,只需要精心地控制發(fā)送的數(shù)據(jù)量就好了,完全不用管什么亂序,重傳之類的。當然我的意思是說,擁塞控制算法中不用管這些,但這并不意味著它們是被放棄的,其它的機制會關(guān)注的,比如SACK機制,RACK機制,RTO機制等。
接下來我們看一下這個delivered以及interval_us的采集是如何實現(xiàn)的。還是像往常一樣,我不準備分析源碼,因為如果分析源碼的話,往往難以抓住重點,過一段時間自己也看不懂了,相反,畫圖的話,就可以過濾掉很多諸如unlikely等異常流或者當前無需關(guān)注的東西:
上圖中,我故意用了一個極端點的例子,在該例子中,我?guī)缀醵际鞘褂玫腟ACK,當X被SACK時,我們可以根據(jù)圖示很容易算出從Delivered為7時的數(shù)據(jù)包被確認到X被確認為止,一共有 12-7=5個數(shù)據(jù)包被確認,即這段時間網(wǎng)絡(luò)上清空了5個數(shù)據(jù)包!我們便很容易算出帶寬值了。我的這個圖示在解釋帶寬計算方法之外,還有一個目的,即說明bbr在計算帶寬時是不關(guān)注數(shù)據(jù)包是否按序確認的,它只關(guān)注數(shù)量,即數(shù)據(jù)包被網(wǎng)絡(luò)清空的數(shù)量。實實在在的計算,不猜Lost,不猜亂序,這些東西,你再怎么猜也猜不準!
計算所得的bw就是bbr此后一切計算的基準。
2.狀態(tài)機
bbr的狀態(tài)機轉(zhuǎn)換圖以及注釋如下圖所示:
通過上述的狀態(tài)機以及上一節(jié)的帶寬計算方式,我們知道了bbr的工作方式:不斷地基于當前帶寬以及當前的增益系數(shù)計算pacing rate以及cwnd,以此2個結(jié)果作為擁塞控制算法的輸出,在TCP連接的持續(xù)過程中,每收到一個ACK,都會計算即時的帶寬,然后將結(jié)果反饋給bbr的pipe狀態(tài)機,不斷地調(diào)節(jié)增益系數(shù),這就是bbr的全部,我們發(fā)現(xiàn)它是一個典型的封閉反饋系統(tǒng),與TCP當前處于什么擁塞狀態(tài)完全無關(guān),其簡圖如下:
這非常不同于之前的所有擁塞控制算法,在之前的算法中,我們發(fā)現(xiàn)擁塞算法內(nèi)部是受外部的擁塞狀態(tài)影響的,比如說在Recovery狀態(tài)下,甚至都不會進入擁塞控制算法,在bbr進入內(nèi)核之前,Linux使用PRR算法控制了Recovery狀態(tài)的窗口調(diào)整,即便說這個時候網(wǎng)絡(luò)已經(jīng)恢復,TCP也無法發(fā)現(xiàn),因為TCP的Recovery狀態(tài)還未恢復到Open,這就是根源!
pacing rate以及cwnd的計算
這一節(jié)好像是重點中的重點,但是我覺得如果理解了bbr的帶寬計算,狀態(tài)機以及其增益系數(shù)的概念,這里就不是重點了,這里只是一個公式化的結(jié)論。
pacing rate怎么計算?很簡單,就是是使用時間窗口內(nèi)(默認10輪采樣)最大BW。上一次采樣的即時BW,用它來在可能的情況下更新時間窗口內(nèi)的BW采樣值集合。這次能否按照這個時間窗口內(nèi)最大BW發(fā)送數(shù)據(jù)呢?這樣看當前的增益系數(shù)的值,設(shè)為G,那么BW*G就是pacing rate的值,是不是很簡單呢?!
至于說cwnd的計算可能要稍微復雜一點,但是也是可以理解的,我們知道,cwnd其實描述了一條網(wǎng)絡(luò)管道(rwnd描述了接收端緩沖區(qū)),因此cwnd其實就是這個管道的容量,也就是BDP!
BW我們已經(jīng)有了,缺少的是D,也就是RTT,不過別忘了,bbr一直在持續(xù)搜集最小的RTT值,注意,bbr并沒有采用什么移動指數(shù)平均算法來“猜測”RTT(我用猜測而不是預測的原因是,猜測的結(jié)果往往更加不可信?。?,而是直接冒泡采集最小的RTT(注意這個RTT是TCP系統(tǒng)層面移動指數(shù)平均的結(jié)果,即SRTT,但brr并不會對此結(jié)果再次做平均!)。我們用這個最小RTT干什么呢?
當前是計算BDP了!這里bbr取的RTT就是這個最小RTT。最小RTT表示一個曾經(jīng)達到的最佳RTT,既然曾經(jīng)達到過,說明這是客觀的可以再次達到的RTT,這樣有益于網(wǎng)絡(luò)管道利用率最大化!
我們采用BDP*G‘就算出了cwnd,這里的G’是cwnd的增益系數(shù),與帶寬增益系數(shù)含義一樣,根據(jù)bbr的狀態(tài)機來獲??!
bbr的細節(jié)淺述
該節(jié)的題目比較怪異,既然是細節(jié)為什么又要淺述??
這是我的風格,一方面,說是細節(jié)是因為這些東西還真的很少有人注意到,另一方面,說是淺述,是因為我一般都不會去分析代碼以及代碼里每一個異常流,我認為那些對于理解原理幫助不大,那些東西只是在研發(fā)和優(yōu)化時才是有用的,所以說,像往常一樣,我這里的這個小節(jié)還是一如既往地去談及一些“細節(jié)”。
1.豪放且大膽的安全探測
在看到bbr之后,我覺得之前的TCP擁塞控制算法都錯了,并不是思想錯了,而是實現(xiàn)的問題。
bbr之所以敢大膽的去探測預估帶寬是因為TCP把更多的權(quán)力交給了它!在bbr之前,很多本應(yīng)該由擁塞控制算法去處理的細節(jié)并不歸擁塞控制算法管。在詳述之前,我們必須分清兩件事:
1)。傳輸多少數(shù)據(jù)?
2)。傳輸哪些數(shù)據(jù)?
按照“上帝的事情上帝管,凱撒的事情凱撒管”的原則,這兩件事本來就該由不同的機制來完成,不考慮對端接收窗口的情況下,擁塞窗口是唯一的主導因素,“傳輸多少數(shù)據(jù)”這件事應(yīng)該由擁塞算法來回答,而“傳輸哪些數(shù)據(jù)”這個問題應(yīng)該由TCP擁塞狀態(tài)機以及SACK分布來決定,誠然這兩個問題是不同的問題,不應(yīng)該雜糅在一起。
然而,在bbr進入內(nèi)核之前的Linux TCP實現(xiàn)中,以上兩個問題并不是分得特別清。TCP的擁塞狀態(tài)只有在Open時才是上述的職責分離的完美樣子,一旦進入Lost或者Recovery,那么擁塞控制算法即便對“問題1):傳輸多少數(shù)據(jù)”都無能為力,在Linux的現(xiàn)有實現(xiàn)中,PRR算法將接管一切,一直把窗口下降到ssthresh,在Lost狀態(tài)則反應(yīng)更加激烈,直接cwnd硬著陸!隨后等丟失數(shù)據(jù)傳輸成功后再執(zhí)行慢啟動。..。在重新進入Open狀態(tài)之前,擁塞控制算法幾乎不會起作用,這并不是一種高速公路上的模式(小碰擦,拍照后停靠路邊,自行解決),更像是鬧市區(qū)的交通事故處理方式(無論怎樣,保持現(xiàn)場,直到交警和保險公司的人來現(xiàn)場處置)。
bbr算法逃離了這一切錯誤的做法,在bbr的patch中,并非只是完成了一個tcp_bbr.c,而是對整個TCP擁塞狀態(tài)控制框架進行了大手術(shù),我們可以從以下的擁塞控制核心函數(shù)中可見一斑:
static void tcp_cong_control(struct sock *sk, u32 ack, u32 acked_sacked,
int flag, const struct rate_sample *rs)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
if (icsk-》icsk_ca_ops-》cong_control) {
// 如果是bbr,則完全被bbr接管,不管現(xiàn)在處在什么狀態(tài)!
/* 目前而言,只有bbr使用了這個機制,但我相信,不久的將來,
* 會有越來越多的擁塞控制算法使用這個統(tǒng)一的完全接管機制!
* 就我個人而言,在幾個月前就寫過一個patch,接管了tcp_cwnd_reduction
* 這個prr的降窗過程。如果當時有了這個框架,我就有福了!
*/
icsk-》icsk_ca_ops-》cong_control(sk, rs);
return;
}
// 否則繼續(xù)以往的錯誤方法!
if (tcp_in_cwnd_reduction(sk)) {
/* Reduce cwnd if state mandates */
// 非Open狀態(tài)中擁塞算法不受理窗口調(diào)整
tcp_cwnd_reduction(sk, acked_sacked, flag);
} else if (tcp_may_raise_cwnd(sk, flag)) {
/* Advance cwnd if state allows */
tcp_cong_avoid(sk, ack, acked_sacked);
}
tcp_update_pacing_rate(sk);
}
在這個框架下,無論處在哪個狀態(tài)(Open,Disorder,Recovery,Lost.。.),如果擁塞控制算法自己聲明有這個能力,那么具體可以傳輸多少數(shù)據(jù),完全由擁塞控制算法自行決定,TCP擁塞狀態(tài)控制機制不再干預!
2.為什么bbr可以忽略Recovery和Lost狀態(tài)
看懂了以上第1點,這一點就很容易理解了。
在第1點中,我描述了bbr確實忽略了Recovery等非Open的擁塞狀態(tài),但是為什么可以忽略呢?一般而言,很多人都會質(zhì)疑,會說bbr采用這么魯莽的方式,最終一定會讓窗口卡住不再滑動,但是我要反駁,你難道不知道cwnd只是個標量嗎?我畫一個圖來分析:
看懂了嗎?不存在任何問題!基本上,我們在討論擁塞控制算法的時候,會忽略流量控制,因為不想讓rwnd和cwnd雜糅起來,但是在這里,它們相遇了,幸運的是,并沒有引發(fā)沖突!
然而,這并不是全部,本節(jié)旨在“淺析”,因此就不會關(guān)注代碼處理的細節(jié)。在bbr的實現(xiàn)中,如果算法外部的TCP擁塞狀態(tài)已經(jīng)進入了Lost,那么cwnd該是多少呢?在bbr之前的擁塞算法中,包括cubic在內(nèi)的所有算法中,當TCP核心實現(xiàn)從將cwnd調(diào)整到1或者prr到ssthresh一直到恢復到Open狀態(tài),擁塞算法無權(quán)干預流程,然而bbr不。雖然說進入Lost狀態(tài)后,cwnd會硬著陸到1,然而由于bbr的接管,在Lost期間,cwnd還是可以根據(jù)即時帶寬調(diào)整的!
這意味著什么?
這意味著bbr可以區(qū)別噪聲丟包和擁塞丟包了!
a)。噪聲丟包
如果是噪聲丟包,在收到reordering個重復ACK后,由于bbr并不區(qū)分一個確認是ACK還是SACK引起的,所以在bbr看來,即時帶寬并沒有降低,可能還有所增加,所以一個數(shù)據(jù)包的丟失并不會引發(fā)什么,bbr依舊會給出一個比較大的cwnd配額,此時雖然TCP可能已經(jīng)進入了Recovery狀態(tài),但bbr依舊按照自己的bw以及調(diào)整后的增益系數(shù)來計算cwnd的新值,過程中并不會受到任何TCP擁塞狀態(tài)的影響。
如此一來,所有的噪聲丟包就被區(qū)別開來了!bbr的宗旨是:“首先,在我的bw計算指示我發(fā)生擁塞之前,任何傳統(tǒng)的TCP擁塞判斷-丟包/時延增加,均全部失效,我并不care丟包和RTT增加”,隨后brr又會說:“但是我比較care的是,RTT在一段時間內(nèi)(隨你怎么配,但我個人傾向于自學習)都沒有達到我所采集到的最小值或者更小的值!這也許意味著著鏈路真的發(fā)生擁塞了!”。..
b)。擁塞丟包
將a)的論述反過來,我們就會得到奇妙的封閉性結(jié)論。這樣,bbr不光是消除了吞吐曲線的鋸齒(ssthresh所致,bbr并不使用ssthresh?。疫€消除了傳統(tǒng)擁塞控制算法(指bbr以及封閉的傻逼Appex之前)的判斷滯后性問題。在cubic發(fā)現(xiàn)丟包進而判斷為擁塞時,擁塞可能已經(jīng)緩解了,但是cubic無法發(fā)現(xiàn)這一點。為什么?原因在于cubic在計算新的cwnd的時候,并沒有把當前的網(wǎng)絡(luò)狀態(tài)(比如bw)當作參數(shù),而只是一味的按照數(shù)學意義上的三次方程去計算,這是錯誤的,這不是一個正確的反饋系統(tǒng)的做法!
基于a)和b),看到了吧,這就是新的擁塞判斷機制!綜合考慮丟包和RTT的增加:
b-1)。如果丟包時真的發(fā)生了擁塞,那么測量的即時帶寬肯定會減少,否則,丟包即擁塞就是謊言。
b-2)。如果RTT增加時真的發(fā)生了擁塞,那么測量的即時帶寬肯定會減少,否則,時延增加即擁塞就是謊言。
bbr測量了即時帶寬,這個統(tǒng)一cwnd和rtt的計量,完全忽略了丟包,因此bbr的算法思想是TCP擁塞控制的正軌!事實上,丟包本就不應(yīng)該作為一種擁塞的標志,它只是擁塞的表現(xiàn)。
3.狀態(tài)機的點點滴滴
我在上文已經(jīng)呈現(xiàn)了關(guān)于STARTUP,DRAIN,PROBE_BW,PROBE_RTT的狀態(tài)圖以及些許細節(jié),當時我指出這個狀態(tài)圖的目標是為了完成bbr的目標,即填滿整個網(wǎng)絡(luò)!在這個狀態(tài)圖看來,所有已知的東西就是當前的即時帶寬,所有可以計算的東西就是增益系數(shù),然后根據(jù)這兩個元素就可以輕易計算出pacing rate和cwnd,是不是很簡單呢?整體看來就是就是這么簡單,但是從細節(jié)上看,不同的pipe狀態(tài)中的增益系數(shù)的計算卻是值得推敲的,以下是bbr處在各個狀態(tài)時的增益系數(shù):
STARTUP:2~3
DRAIN:pacing rate的增益系數(shù)為1000/2885,cwnd的增益系數(shù)為1000/2005+1。
PROBE_BW:5/4,1,3/4,bbr在PROBE_BW期間會隨機在這些增益系數(shù)之間選擇當前的增益系數(shù)。
PROBE_RTT:1。但是在探測RTT期間,為了防止丟包,cwnd會強制cut到最小值,即4個MSS。
我們可以看到,bbr并沒有明確的所謂“降窗時刻”,一切都是按照狀態(tài)機來的,期間絲毫不會理會TCP是否處在Open,Recovery等狀態(tài)。在此前的擁塞控制算法中,除了Vegas等基于延時的算法會在計算得到的target cwnd小于當前cwnd時視為擁塞而在算法中降窗外,其它的所有基于丟包的算法中均是檢測到丟包(RTO或者reordering個重復ACK)時降窗的,可悲的是,這個降窗過程并不受擁塞算法的控制,擁塞算法只能消極地給出一個ssthresh值,即降窗的目標,這顯然是令人無助的!
bbr不再關(guān)注丟包事件,它并不把丟包當成很嚴重的事,這事也不歸它管,只要TCP擁塞狀態(tài)機控制機制可以合理地將一些包標記為LOST,然后重傳它們便是了,bbr能做的僅僅是告訴TCP一共可以發(fā)出去多少數(shù)據(jù),僅此而已!然而,如果TCP并沒有把LOST數(shù)據(jù)包合理標記好,bbr并不care,它只是根據(jù)當前的bw和增益系數(shù)給出下一個pacing rate以及cwnd而已!
4.關(guān)于Sched FQ
這里涉及的是bbr之外的東西,F(xiàn)air queue!在bbr的patch最后,會發(fā)現(xiàn)幾行注釋:
NOTE: BBR *must* be used with the fq qdisc (“man tc-fq”) with pacing
enabled, since pacing is integral to the BBR design and
implementation. BBR without pacing would not function properly, and
may incur unnecessary high packet loss rates.
記住這幾行文字并理解它們。
這是bbr最為重要的一方面。雖然說Linux的TCP實現(xiàn)早就支持的pacing rate,但直到4.8版本都沒有在TCP層面支持它,很大的一部分原因是因為借助已有的FQ可以很完美地實現(xiàn)pacing rate!TCP可以借助FQ來實現(xiàn)平緩而非突發(fā)的數(shù)據(jù)發(fā)送!
關(guān)于FQ的詳細內(nèi)容可以去看相關(guān)的manual和源碼,這里要說的僅僅是,F(xiàn)Q可以根據(jù)bbr設(shè)置的pacing rate將一個cwnd內(nèi)的數(shù)據(jù)的發(fā)送從“突發(fā)到網(wǎng)絡(luò)”這種行為變換到“平緩發(fā)送到網(wǎng)路”的行為,所謂的平緩發(fā)送指的就是數(shù)據(jù)包是按照帶寬速率計算的間隔一個個發(fā)送到網(wǎng)絡(luò)的,而不是突發(fā)進網(wǎng)絡(luò)的!
這樣一來,就給了網(wǎng)絡(luò)緩存以緩解的機會!記住,關(guān)鍵問題是bbr會在每收到ACK/SACK時計算bw,這個精確的測量不會漏掉任何可乘之機,即便當前網(wǎng)絡(luò)擁塞了,它只要能在下一時刻恢復,bbr就可以發(fā)現(xiàn),因此即時帶寬通??梢员憩F(xiàn)這一點!
5.其它
還有關(guān)于令牌桶監(jiān)管發(fā)現(xiàn)(lt policed)的主題,long term采樣的主題,留到后面的文章具體闡述吧,本文已經(jīng)足夠長了。
6.bufferbloat問題
關(guān)于深隊列,數(shù)據(jù)包如何如何長時間排隊但不丟包卻引發(fā)RTO,對于淺隊列,數(shù)據(jù)包如何如何頻繁丟包。..談起這個話題我一開始想滔滔不絕,后來想罵人,現(xiàn)在我三緘其口!任何人都知道端到端的QoS是一個典型的反饋系統(tǒng),但是任何人都只是夸夸其談,我選擇的是閉口不說,如果非要我說,我的回答就是:不知道!
這是一個怎么說都能對又怎么說都能錯的話題,就像股票預測那樣,所以我選擇閉嘴。
bbr算法到來后,單單從公共測試結(jié)果上看,貌似解決了bufferbloat問題,也許吧,也許。bbr好像真的開始在高速公路上飚車了。..最后給出一個測試圖,來自《A quick look at TCP BBR》:
bbr代碼的簡單性和復雜性
我一向覺得TCP擁塞控制算法太過復雜,而復雜的東西基本上就是用來裝逼的垃圾,直到遇到了bbr。
Neal Cardwell提供的patch簡單而又直接,大家可以從 該bbr的pach上一看究竟!在bbr模塊之外,Neal Cardwell主要更改了tcp_ack函數(shù)里面關(guān)于delivered計數(shù)的部分以及擁塞控制主函數(shù),這一切都十分顯然,只要patch代碼就可以一目了然。在數(shù)據(jù)包被發(fā)送的時候-不管是初次發(fā)送還是重傳,均會被當前TCP的連接狀況記錄在該數(shù)據(jù)包的tcp_skb_cb中,在數(shù)據(jù)包被應(yīng)答的時候-不管是被ACK還是被SACK,均會根據(jù)當前的狀態(tài)和其tcp_skb_cb中狀態(tài)計算出一個帶寬,這些顯而易見的邏輯相比任何人都應(yīng)該知道哪里的代碼被修改了!
然而,這種查找和確認的工作太令人感到悲哀,讀懂代碼是容易的,移植代碼是無聊的,因為時間卡的太緊!我必須要說的是,如果一件感興趣的事情變成了必須要完成的工作,那么做它的激情起碼減少了1/4,OK,還不算太壞,然而如果這個必須完成的工作有了deadline,那么激情就會再減少1/4,最后,如果有人在背后一直催,那么完蛋,這件事可以瞬間完成,但是我可以鄭重說明這是湊合的結(jié)果!但是實際上,這件事本應(yīng)該可以立即快速有高質(zhì)量的完成并驗收!
寫在最后
我本來應(yīng)該可以把本文寫的更長些,但是打住了,因為我沒有時間,沒有精力,更沒有業(yè)務(wù)去繼續(xù),我寫這一切純粹是閑的,周末比較無聊,所以信手拈來幾筆畫了幾張圖,完成了本文。
我之所以不繼續(xù)下去的原因更多的是只是因為沒有時間!我比較討厭急功近利,我比較喜歡工匠精神,一種時間打磨精品的精神,一種自由引導創(chuàng)造的精神,如果沒有時間,什么都是掰扯!
比較諷刺的是,這個bbr算法顯然不是一個“一周或者兩周搞定的算法”,但是中國人卻希望花更少的時間去將其“拿來”就用。..。中國人認為任何事情都是可以靠加班可以解決的,所謂愚公移山,精衛(wèi)填海,鐵杵磨針,人心齊泰山移的精神早已深入人心,殊不知這種XX行徑根本經(jīng)不起推敲,你把全中國14億不止的人聚集起來一起去推泰山,看能推得動么?你真的用一根鐵杵去磨針么?為什么不去想著買針???傻逼!我不說了,本文所寫的技術(shù)中透露的態(tài)度,與生活無關(guān),亦與工作無關(guān),這種態(tài)度完全是我自己一個人的世界,與不理解以及反對的人,不討論,不爭論,不辯論。..!技術(shù)是大家的,態(tài)度是個人的。
編輯:hfy
電子發(fā)燒友App


























評論