壅塞與流量控制

TCP CUBIC

/ CUBIC: KEW-bik /

傳統 TCP 在一次遺失之後,每個往返把視窗增大一個封包。在慢速的本地連結上這沒問題,但在非常快、長距離的連結上——一條通往另一塊大陸的 gigabit 管線——遺失後一次一個封包地重新填滿視窗,可能真的要花上好幾分鐘,讓大部分頻寬閒置。CUBIC 就是對攀升方式的重新設計,用以修正這點,它多年來一直是 Linux(也因此是全世界極大比例伺服器)的預設壅塞控制器。

關鍵概念就在名字裡:遺失之後,CUBIC 讓壅塞視窗沿著一條對「時間」的三次方曲線成長,而非一條直線。剛砍完視窗時,它快速攀升以回到遺失發生時的視窗大小附近(稱為高原,或 W_max)。當它接近那個被記住的天花板時便放慢、謹慎試探——這是三次方曲線中間的平坦段——而若那裡沒有遺失,它就再次加速越過它,去發掘新騰出的容量。巧妙的是,這個成長是「自上次遺失以來的真實時間」的函數,而非往返次數的函數,這使得 CUBIC 在 RTT 差很多的流之間,表現得比傳統 AIMD 更公平。

CUBIC 本質上仍是基於遺失的:和 Reno 一樣,它把丟掉的封包當成退讓的信號,並繼承同樣的盲點——它分不清壅塞遺失與隨機的無線遺失,而且傾向把路由器緩衝區塞滿(助長了緩衝膨脹),因為它只在緩衝區溢位之後才退讓。但對於高速有線連結這個常見情況,它遠比舊的線性攀升更有效率,這正是它今天悄悄承載著巨大比例網際網路流量的原因。

在一條 10 Gbps 的跨洲連結上,傳統 Reno 在遺失後可能每 150 毫秒 RTT 才加一個 1500 位元組的封包——耗時好幾分鐘才慢慢爬回全速。CUBIC 則以它的三次方曲線飛奔回先前的視窗附近,在舊天花板周圍趨平以溫和試探,然後再越過它,於是用幾秒、而非幾分鐘就恢復了全速吞吐量。

CUBIC 基於時間的三次方攀升,比 Reno 每 RTT 一個封包的直線,遠更快地填滿一條又快又長的路徑。

CUBIC 比 Reno 更有效率,但和 Reno 共享核心弱點:它是基於遺失的,所以仍會把無線錯誤遺失誤認為壅塞,而且傾向先把緩衝區填滿才退讓,加劇緩衝膨脹與延遲。BBR 的誕生,部分正是為了改用對路徑建模的方式,來擺脫這些基於遺失的限制。

又称
CUBICCUBIC TCP立方 TCP