揭露 bbr 的真相

信 bbr 的伙计们,我又要泼冷水了,哈哈。

从先 bbr 的海报开始,相信大家也是被它唬住的:

注意横坐标标度是对数,这就凸显了优势。

把它展开到自然数坐标,再把其它对照画在一个坐标系里,在此之前,须知的前置知识是 aimd 算法的吞吐与丢包率的关系(正好是上图的红线):
T = α 1 R T T 1 p T=\alpha\dfrac{1}{RTT}\sqrt{\dfrac{1}{p}} T=αRTT1p1

重画上图如下图所示:

可见,bbr 只是 pixie 的变体,而 cycle_len = 2 也只是柔和版的 pixie:如果将 cycle_len 和 filter_win 缩小到 2,bbr 就是一个每次以 5/4 增益发包的 pixie 算法,如果 cycle_len 恢复为 8,它就是每 8 周期以 5/4 增益发包,期间保持 maxbw 的 pixie 算法,cycle_len 越大,对 rtt 变化越迟钝。

丝毫看不出 bbr 有 "拥塞控制" 含义。过了这么多年,那张抗 20% 丢包的海报不值得推荐。无论抗随机丢包,还是抗拥塞丢包,都是保带宽,只会加剧拥塞。详情参见:bbr 真的抗丢包吗。

拥塞多由突发导致,多数转瞬即逝,至少不恒久持续,拥塞发生时的高响应度很重要,但 bbr 对时延不敏感,做不到高响应度。

分析 pixie(记住 bbr 只是柔和版 pixie) 算法,pacing_rate = deliver_rate / (1 - p) 旨在用超量发送弥补丢包损耗,只为保带宽,但多发出的包依丢包率 p 是要丢掉的,此发送能耗为保带宽而浪费了,在丢包点上游,多余流量反而加剧拥塞,此举从头到尾接近无用功甚至净损耗。

现在来看 aimd(以 cubic 为例),给定丢包率 p,吞吐 T 一一对应,T 和 p 相互依赖,这才能构成稳定的拥塞控制基础,不像 bbr 和 pixie,T 由 发送行为决定,发得越多,吞吐越大,很容易跑飞。

注意到 cubic 的 T-p 曲线下凸,随 p 增加,T 降低变慢,注意到丢包率 p 由 buffer 大小决定,buffer 越大,p 越小,这又引出 cubic 和 bbr 对 buffer 依赖的不同风格。

从 n 条流完全同步和 n 条流完全异步作为两个极端分析。

对于 cubic/aimd,给定 p,n 条流总吞吐 T(n) 在完全异步(单流丢包率 p)时的 T ( n ) = n ∗ p − 0.5 T(n)=n*p^{-0.5} T(n)=n∗p−0.5和完全同步(单流丢包率 n*p)时的 T ( n ) = n ∗ ( n p ) − 0.5 = n ∗ p − 0.5 T(n)=n*(np)^{-0.5}=\sqrt{n}*p^{-0.5} T(n)=n∗(np)−0.5=n ∗p−0.5之间,上凸意味着收敛,随 bw,n 增加,所需 buffer 虽可能(仅n增加,buffer 甚至可以减少)也增加,但增速相比 bw 和 n 而言更慢。详见 交换机平方反比律,主要是引用的这篇论文:Sizing Router Buffers

再看 bbr/pixie,给定 p,n 条流总吞吐 T(n) 在完全异步时的 T ( n ) = 1 1 − p T(n)=\dfrac{1}{1-p} T(n)=1−p1和完全同步时的 T ( n ) = 1 1 − n p T(n)=\dfrac{1}{1-np} T(n)=1−np1之间,下凸意味着发散,随着 bw,n 增加,所需 buffer 越大,bbr 限制 cwnd 作为 secondary controller 基于此。

但随网络规模扩大,n 必然增加。

把上面的画成图看一下(原始推导采用高斯分布定量计算,不太直观,我这里采用凸凹性定性分析):

再重复,bbr 就是一个温和版的 pixie。

改进?还是要回到 aimd,正如 bbr2,bbr3 所做的。增加灵敏度也是必须的,哪个拥塞能持续配置参数那么久还不介入,所以还是我那个自适应 maxfilter win 沾边儿:提高 bbr 灵敏性,也不能光感知下降而不弥补上升,参见这篇:bbr2 cruise 阶段的 inflight 补偿

说白了,bbr 就像是猜硬币正反时为了更精确而引入了地转偏向力,最后其实还不如猜 50%,于是 bbr 最终也还是回归了 aimd。

如果你想让吞吐表现得良好,又不想用 pixie,那么请用 bbr1,而不是 bbr2,bbr3,因为后面这两个是做拥塞控制的,bbr1 是做传输加速的。

最后说说如何测试。

如果你没有真实环境而非要用 Linux tc 工具模拟,千万不要再用 netem loss random 1%,netem loss 1%,这种随机丢包只能应付一下经理,一定要用 4-state markov,它的配置如下:

bash 复制代码
tc qdisc add dev eth0 root netem loss state $p13 $p31 $p32 $p23 $p14

其中状态 1,2,3,4 分别为:

这就能更逼真地模拟实际中的突发拥塞丢包和随机噪声丢包交错对 cc 的影响了,而 cc 的表现更加不同。

此外,用 iperf3 而不是 iperf,观察 Retr 就能估算重传率和丢包率了。

皮鞋没有蹬上,露着白袜子。

浙江温州皮鞋湿,下雨进水不会胖。

相关推荐
邂逅岁月4 天前
【网络原理】❤️Tcp 连接管理机制❤️ “三次握手” “四次挥手”的深度理解, 面试最热门的话题,没有之一, 保姆式教学 !!!
网络·tcp/ip·计算机网络·面试·tcp·网络连接·tcp机制
怀九日8 天前
网络高级(学习)2024.9.11
网络·网络协议·学习·tcp/ip·tcp·modbus·rtu
轩轶子10 天前
【C-实践】文件服务器(1.0)
服务器·c语言·小程序·tcp
不想秃头的烟花13 天前
传输层(TCP、UDP、RDT详解)
udp·tcp·连接管理·流量控制·传输层·rdt·可靠数据传输
yunteng52114 天前
区块链-P2P(八)
网络协议·区块链·tcp·p2p
红客59715 天前
TCP如何关闭连接(详细版)
网络·网络协议·tcp
开出南方的花15 天前
python进阶篇-day05-网络编程(TCP)与进程
开发语言·网络·python·网络协议·numpy·tcp·httpx
山水阳泉曲17 天前
网络传输加密及openssl使用样例(客户端服务器)
服务器·网络·安全·区块链·密码学·ssl·tcp
dog25019 天前
bbr 和 inflight 守恒的收敛原理
bbr·拥塞控制
Lullaby—19 天前
JavaEE-传输层协议
网络协议·java-ee·tcp