协议层面的延迟:TCP的拥塞控制与慢启动
跨云数据复制,说白了就是数据在广域网上跑。而广域网,几乎都跑在TCP之上。TCP是个好东西,可靠、有序、流量控制,样样都行。但它的这些特性,在跨云场景下,恰恰成了延迟的“帮凶”。
我个人习惯把TCP的延迟问题拆成三块来看:建连开销、慢启动的吞吐爬坡、以及窗口大小对延迟的放大效应。咱们一个一个聊。
TCP三次握手:还没发数据,先耗一个RTT
你想想看,客户端想跟服务端传数据,得先握个手。这个握手过程,至少消耗一个往返时间(RTT)。对于跨云场景,RTT动辄几十毫秒甚至上百毫秒,这个开销就很可观了。
具体流程是这样的:
- 客户端发SYN(同步序列编号)
- 服务端回SYN+ACK(同步确认)
- 客户端再回ACK(确认)
三次握手完成后,才能开始传数据。也就是说,在第一个数据包发出之前,你已经等了一个RTT。
关键点:对于短连接场景(比如频繁的API调用),三次握手带来的延迟占比极高。我建议在跨云复制中尽量使用长连接或连接池,避免每次传输都重新建连。
我的经验:我曾经优化过一个跨中美两地的数据同步任务。原始方案每次同步都新建TCP连接,光握手就耗掉200多毫秒。改成连接池复用后,整体延迟下降了近40%。
慢启动算法:吞吐量的“爬坡”过程
TCP建连之后,并不会立刻把带宽跑满。它会从一个小窗口开始,慢慢试探网络的承载能力。这个过程,就是慢启动。
慢启动的核心逻辑:
- 初始拥塞窗口(cwnd)通常为10个MSS(最大报文段长度)
- 每收到一个ACK,cwnd翻倍(指数增长)
- 直到遇到丢包或达到慢启动阈值(ssthresh)
问题在于,跨云链路的带宽延迟积(BDP)通常很大。比如一个100Mbps的链路,RTT是100ms,BDP大约是1.25MB。而慢启动从10个MSS(约14KB)开始爬,要爬很多个RTT才能填满这个管道。
| RTT次数 | 拥塞窗口(MSS) | 吞吐量(Mbps) |
|---|---|---|
| 0 | 10 | 1.2 |
| 1 | 20 | 2.4 |
| 2 | 40 | 4.8 |
| 3 | 80 | 9.6 |
| 4 | 160 | 19.2 |
| 5 | 320 | 38.4 |
| 6 | 640 | 76.8 |
| 7 | 1280 | 153.6 |
看到没?要跑满100Mbps的链路,需要6个RTT。如果RTT是100ms,那就是600ms的“爬坡时间”。对于短时间的数据传输,这个开销占比极高。
注意:慢启动不是“慢”,而是“谨慎”。它是在保护网络不被突发流量冲垮。但在跨云场景下,这个谨慎的代价就是延迟。
窗口大小与延迟的关系
TCP的窗口大小,决定了发送端在收到ACK之前能发多少数据。窗口越大,链路利用率越高,但延迟也越高——因为数据在缓冲区里排队。
这里有个关键公式:
吞吐量 = 窗口大小 / RTT
也就是说,要提升吞吐量,要么增大窗口,要么减小RTT。RTT是物理距离决定的,很难改。所以只能增大窗口。
但窗口不是无限大的。接收窗口(rwnd)受接收端缓冲区限制,拥塞窗口(cwnd)受网络状况限制。两者取最小值,才是实际可用窗口。
我遇到过一种情况:接收端缓冲区配得太小,导致窗口始终打不开。明明链路带宽很足,但吞吐量就是上不去。后来把接收窗口从64KB调到1MB,问题立刻解决了。
核心结论:窗口大小与延迟是“跷跷板”关系。窗口越大,延迟越高(因为排队),但吞吐量也越高。跨云复制需要在吞吐量和延迟之间做权衡。
BBR:新型拥塞控制算法
传统TCP的拥塞控制(比如CUBIC)依赖丢包来探测带宽。但跨云链路上,丢包不一定是拥塞导致的,可能是链路本身的质量问题。这就导致传统算法会过度降速,白白浪费带宽。
BBR(Bottleneck Bandwidth and Round-trip propagation time)是Google提出的一种新算法。它不依赖丢包,而是通过测量带宽和RTT来建模网络状态。
BBR的核心思路:
- 测量瓶颈带宽(BtlBw)
- 测量最小RTT(RTprop)
- 根据这两个值计算最优发送速率
BBR的优势很明显:
- 不依赖丢包,不会因为偶然丢包而大幅降速
- 能更充分地利用高带宽长链路
- 延迟更低,因为不会把缓冲区填满
我曾在AWS和阿里云之间的数据传输中测试过BBR。同样的链路,CUBIC的吞吐量只有40Mbps左右,换成BBR后直接跑到95Mbps。延迟也从120ms降到了80ms。
我的建议:如果你的跨云链路RTT超过50ms,或者带宽超过100Mbps,强烈建议试试BBR。Linux内核4.9以上版本已经内置支持,开启方式很简单:
# 查看当前拥塞控制算法
sysctl net.ipv4.tcp_congestion_control
# 切换到BBR
echo "bbr" > /proc/sys/net/ipv4/tcp_congestion_control
本章知识体系
下面这张图,把TCP协议层面的延迟问题串起来了:
这张图把TCP延迟的三个核心问题串在了一起。三次握手是建连阶段的固定开销,慢启动是传输初期的吞吐爬坡,窗口大小则决定了稳态下的延迟与吞吐量关系。而BBR,正是针对这些问题给出的一个系统性解决方案。
嗯,协议层面的延迟,说白了就是TCP的“好心办坏事”。它太想可靠了,太想公平了,结果在跨云这种高延迟、高带宽的场景下,反而成了瓶颈。下一层,咱们聊聊网络层面的延迟——路由、丢包、抖动,那又是另一番风景。