在没有打开bbr之前。IPerf3结果如下:分别是单线程和多线程。为什么差距巨大?
5] 7.00-8.00 sec 2.50 MBytes 21.0 Mbits/sec 2 218 KBytes
[ 8] 7.00-8.00 sec 8.75 MBytes 73.4 Mbits/sec 0 628 KBytes
[ 10] 7.00-8.00 sec 7.50 MBytes 62.9 Mbits/sec 0 421 KBytes
[SUM] 7.00-8.00 sec 18.8 MBytes 157 Mbits/sec 2
- - - - - - - - - - - - - - - - - - - - - - - - -
[ 5] 8.00-9.00 sec 2.50 MBytes 21.0 Mbits/sec 0 245 KBytes
[ 8] 8.00-9.00 sec 7.50 MBytes 62.9 Mbits/sec 0 630 KBytes
[ 10] 8.00-9.00 sec 6.25 MBytes 52.4 Mbits/sec 0 457 KBytes
[SUM] 8.00-9.00 sec 16.2 MBytes 136 Mbits/sec 0
- - - - - - - - - - - - - - - - - - - - - - - - -
[ 5] 9.00-10.00 sec 3.75 MBytes 31.5 Mbits/sec 0 261 KBytes
[ 8] 9.00-10.00 sec 8.75 MBytes 73.4 Mbits/sec 0 639 KBytes
[ 10] 9.00-10.00 sec 7.50 MBytes 62.9 Mbits/sec 0 520 KBytes
[SUM] 9.00-10.00 sec 20.0 MBytes 168 Mbits/sec 0
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.05 sec 35.9 MBytes 29.9 Mbits/sec 442 sender
[ 8] 0.00-10.05 sec 82.8 MBytes 69.0 Mbits/sec 1050 sender
[ 10] 0.00-10.05 sec 69.6 MBytes 58.1 Mbits/sec 1629 sender
[SUM] 0.00-10.05 sec 188 MBytes 157 Mbits/sec 3121 sender
-----------------------------------------------------------
Server listening on 5201 (test #3)
-----------------------------------------------------------
56512
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 1.32 MBytes 11.1 Mbits/sec 3 43.2 KBytes
[ 5] 1.00-2.00 sec 502 KBytes 4.11 Mbits/sec 4 16.7 KBytes
[ 5] 2.00-3.00 sec 251 KBytes 2.06 Mbits/sec 4 8.37 KBytes
[ 5] 3.00-4.00 sec 251 KBytes 2.06 Mbits/sec 1 13.9 KBytes
[ 5] 4.00-5.00 sec 251 KBytes 2.06 Mbits/sec 2 18.1 KBytes
[ 5] 5.00-6.00 sec 251 KBytes 2.06 Mbits/sec 3 9.76 KBytes
[ 5] 6.00-7.00 sec 251 KBytes 2.06 Mbits/sec 2 9.76 KBytes
[ 5] 7.00-8.00 sec 251 KBytes 2.06 Mbits/sec 1 15.3 KBytes
[ 5] 8.00-9.00 sec 251 KBytes 2.06 Mbits/sec 2 16.7 KBytes
[ 5] 9.00-10.00 sec 251 KBytes 2.06 Mbits/sec 1 20.9 KBytes 这是一个非常经典的长肥网络(LFP, Long-Fat Pipe)在没有优化情况下的表现。单线程和多线程之所以差距如此巨大(2.06 Mbps vs 157 Mbps),是因为传统 TCP 算法(如 CUBIC)在“高延迟+轻微丢包”环境下的天然缺陷。
以下是详细的分析:
1. 传统算法对丢包的“过度反应”
在没有开启 BBR 之前,你的 VPS 默认使用 CUBIC 或 Reno 算法。这些算法的核心逻辑是:丢包 = 拥塞。
- 单线程: 观察你的单线程数据,每秒都有 1-4 次重传(Retr)。一旦 CUBIC 监测到一个丢包,它会认为网络“堵死了”,立刻将拥塞窗口(Cwnd)砍掉一半甚至更多(比如从 43KB 直接降到 8.37KB)。
- 后果: 你的窗口还没等爬升起来,下一个丢包又来了。结果就是 Cwnd 始终被压制在几 KB 到几十 KB 之间,速度自然锁死在 2 Mbps 左右。
2. 高延迟(200ms)放大了恢复难度
TCP 窗口的增长是需要时间的(每一个 RTT 往返才增长一点)。
- 由于你的延迟高达 200ms,这意味着一秒钟内窗口只能进行 5 次“反馈循环”。
- 如果窗口被砍掉,它需要好几秒钟才能恢复到之前的水平。但在不稳定的长途线路上,几秒钟内几乎肯定会再次发生微小丢包。
- 数学直观: $Bitrate = \frac{Cwnd}{RTT}$。当 $Cwnd$ 被限制在 20 KB 时,你的理论速度就是 $\frac{20 \text{ KB}}{0.2 \text{ s}} \times 8 \approx 0.8 \text{ Mbps}$。这和你看到的 2 Mbps 非常吻合。
3. 多线程为什么能“力大砖飞”?
多线程(-P 3)之所以能跑到 157 Mbps,是因为它在物理层面上“作弊”了:
- 风险分担: 每个线程都有自己独立的 $Cwnd$。当线程 A 因为丢包而减速时,线程 B 和 C 可能正处于高速阶段。
- 独立恢复: 三个线程同时在“抢”带宽,即便每个线程都因为丢包而表现不佳,但它们累加起来的窗口总和远大于单个线程能达到的上限。
- 观察重传数: 你的多线程测试在 10 秒内产生了 3121 次重传。这证明了链路上其实有很多丢包或抖动,单线程会被这些重传彻底“吓死”,而多线程靠着数量优势强行把数据塞了过去。
4. 数据对比总结
| 特性 | 单线程 (Thread 5) | 多线程 (SUM) |
|---|---|---|
| 平均速率 | 2.06 Mbits/sec | 157 Mbits/sec |
| Cwnd 表现 | 极小且持续萎缩 (8.37K - 43K) | 多个线程窗口互补,总和较大 |
| 重传影响 | 致命,导致连接进入持续的“慢启动”或“拥塞避免” | 较大,但被多连接的并行性抵消 |
这就是为什么要开 BBR
BBR 的革命性在于:它不再把丢包当作拥塞的唯一信号。
- BBR 会测量延迟和带宽,只要它认为管道还没满,即便有丢包,它也会维持甚至增加发送速率。
- 如果你现在开启 BBR,你会发现单线程的速度会立刻从 2 Mbps 飙升到接近多线程的水平(甚至更高)。