一台 100M 端口的机器,往对端搬一个几十 G 的备份包,监控曲线贴在底部不动,传输工具里那个数字稳稳地停在几 MB/s。重启过、换过盘、加过内存,甚至怀疑过对端机器不行。把端口翻一倍再试,数字还是那样——这就是最典型的现场。
先把结论摆在前面,后面再一笔一笔算:
一、单条 TCP 流的速度上限不是带宽,是「接收窗口 ÷ 往返时延」。窗口不变,你把端口从 100M 加到 1G,单流速度一分钱都不会涨。
二、跨境链路的往返时延比同城高一个数量级,同样一个窗口,跨一次洋就掉一个数量级的速度。「长肥管道」这个词说的就是这件事。
三、判断顺序必须是:先算 BDP → 再上并发与多流 → 换协议换工具排在末位。顺序反过来,等于花钱买带宽买了个寂寞。
四、并发不是免费的。开到一定条数之后,排队、乱序、重传放大会把增量吃掉,甚至倒扣。
五、真到了几百 G、几个 T 的级别,最有效的办法往往不是把管道调粗,而是别让它走公网——增量、中转、甚至物理搬运。
TCP 是个「发了要等确认」的协议。发送端在任意时刻能扔到线路上的、还没被确认的数据量,不能超过接收端通告的窗口。也就是说,一个往返周期里最多只能推一个窗口的数据出去。于是有个很朴素的算式:
单流吞吐上限 ≈ 接收窗口大小 ÷ 往返时延(RTT)
这个「窗口 ÷ 时延」的乘积反过来写,就是业内常说的带宽时延积(BDP):带宽 × 往返时延 = 要把管道填满,窗口至少得有多大。两个说法是一回事,一个从窗口推速度,一个从带宽推窗口。
拿几个数算一遍,下面全是理论值与示例,用来建立量级感,不是任何一条真实链路的测量结果:
例一:接收窗口 64KB,往返时延 200ms。一个往返周期 0.2 秒,最多推 64KB 出去,折合 64×1024×8 ÷ 0.2 ≈ 2.6 Mbps,约 0.33 MB/s。这就是很多老机器、老内核、或者中间设备把窗口压小之后的样子——明明挂的是 100M 口,跑出来几百 KB/s。
例二:窗口开到 256KB,往返时延还是 200ms。吞吐 ≈ 256×1024×8 ÷ 0.2 ≈ 10.5 Mbps,约 1.3 MB/s。窗口翻了四倍,速度翻四倍,端口依然闲着。
例三:开启窗口缩放,窗口给到 1MB,往返时延 200ms。吞吐 ≈ 1×1024×1024×8 ÷ 0.2 ≈ 41.9 Mbps,约 5.2 MB/s。这时候才开始有点像话,但离 100M 端口的 12.5 MB/s 理论上限还差着。
例四:窗口 2MB,往返时延 200ms。吞吐 ≈ 2×1024×1024×8 ÷ 0.2 ≈ 83.9 Mbps,约 10.5 MB/s。这一条流已经能把 100M 端口吃到八成以上。
例五:同样的 64KB 窗口,把往返时延换成 30ms(同城或同区域内的量级)。吞吐 ≈ 64×1024×8 ÷ 0.03 ≈ 17.5 Mbps,约 2.2 MB/s。看清楚:窗口一点没改,只是时延从 200ms 变成 30ms,单流就涨了近七倍。
这组算式说明一件事——在跨境场景里,时延是分母,而且是个大分母。端口是 100M 还是 1G,只在窗口足够大、或者并发足够多的时候才轮得到它说话。
理论上现代系统的窗口早就支持缩放到 MB 级,实际跑起来却常常停在几十 KB,原因通常就这么几个,都值得一项一项去核:
一是内核的发送/接收缓冲最大值设得保守。很多发行版默认的接收缓冲上限只有几 MB,而且自动调节的步进很慢,短连接根本爬不到上限。出现了「刚开头很慢、跑一会儿变快」的曲线,多半就是缓冲还在爬。
二是窗口缩放选项没生效。TCP 窗口字段本身只有 16 位,最大 64KB,超过这个数要靠握手时协商的窗口缩放因子。只要路径上有某台设备把这个选项处理坏了(部分老旧防火墙、做 TCP 归一化的中间盒),两端就算配了 4MB 缓冲,实际生效的还是 64KB。这类问题最阴,因为你在自己机器上查参数全是对的。
三是应用没把 socket 缓冲调起来。内核允许 4MB,应用只申请了默认大小,那就是按应用的来。很多传输工具自带缓冲设置项,不设就是默认值。
四是拥塞控制窗口(cwnd)根本没长大。接收窗口是天花板,cwnd 是当前实际敢发多少。刚起步的慢启动、中途一次丢包导致的减半,都会让 cwnd 长期低于天花板。
业内把「带宽不小、时延很大」的链路叫长肥管道(Long Fat Network,缩写 LFat 或 LFN)。「长」说的是时延长,「肥」说的是带宽大。这两个字凑到一起,正好是单流最容易翻车的组合:管道很长,意味着一窗口数据要很久才轮得回来确认;管道很肥,意味着窗口必须很大才填得满。
同城或者同区域里,往返时延是毫秒到十几毫秒的量级,就算窗口只有 64KB,单流也能跑出十几 Mbps,日常体感不明显。跨到洲际,往返时延一下跳到一两百毫秒甚至更高,同样的窗口直接掉一个数量级。业务方感知到的「跨境特别慢」,本质上是时延把同一个窗口除掉了十倍,跟海底光缆的容量没什么关系。
这条链路还有个容易被忽略的特点:带宽是「买」来的,时延是「地理」给的。光纤里的传播速度是固定的,跨太平洋一个来回的光程就是那么多,你把端口从 100M 升到 10G,往返时延一毫秒都不会降。所以在这类链路上,加带宽是加法,加窗口和加并发才是乘法。
再补一句关于路径的。跨境链路的往返时延里,不只有光纤传播时间,还有每一跳的排队与处理时间、跨境出口的收敛与调度时间。晚高峰时段排队时延抬上去,分母又变大一点,速度再掉一截——这也是为什么同一个传输任务,凌晨跑和晚上八点跑,数字能差出一截。这里说的是普遍规律,具体多少要自己测自己那条路。
怀疑归怀疑,总得有个能把话说死的验证。做法不复杂,两轮对比就够了。
用一条流跑,记下稳定后的速度。同时把这条连接的 cwnd 和往返时延取出来(Linux 上可以用 ss -i 看每条连接的拥塞窗口、往返时延、重传情况),看 cwnd 有没有接近你配置的接收窗口上限。如果 cwnd 长期停在 64KB 附近,那就是窗口缩放没谈成;如果 cwnd 很大但速度还是低,那问题在别处(丢包、限速、对端处理不过来)。
顺手把往返时延单独测一下。用 ping 拿到一个粗略值就够了,重点是确认它是不是你以为的那个量级。有些链路看着是直连,实际绕了半个地球,时延比预期高一倍,这种情况并不少见。
开 4 条、8 条、16 条并行,分别记速度。判据很直接:
如果并发条数往上加,总吞吐也近似线性往上走——4 条是单流的四倍左右,8 条是八倍左右——那就坐实了是单流窗口被时延卡住。这是最好办的那种情况,因为答案是明确的方向明确的。
如果并发加上去,总吞吐很快压平,2 条就到顶,再加反而抖——那瓶颈在别处:端口被限速了、对端写盘跟不上、链路中间有整形丢包、或者总带宽本来就那么多。这时候再堆并发只会把抖动做大。
如果单流就已经很接近端口理论速率(比如 100M 端口跑出 11 MB/s 上下),那就别折腾了,你这单根本不慢,慢的是总量大或者跑得晚。
再加一个对照:同一对机器之间跑内网/同城,或者把对端换成同区域的另一台。如果同城很快、跨境很慢,范围就锁定在跨境这一段;如果同城也慢,先回去查机器、查盘、查网卡,别在 TCP 参数上磨。
下面这张表全部是理论计算示例,用来建立量级感,不是对任何一条真实链路的实测结果。端口速率按常见的 100Mbps(理论 12.5 MB/s)作为参照,「需要多少并发」一栏是理论除法结果,实际要留余量。
| 往返时延(示例取值) | 窗口大小 | 理论单流吞吐 | 接近 100M 端口需多少并发 | 备注 |
|---|---|---|---|---|
| 30ms(同城/同区域量级) | 64KB | 约 17.5 Mbps / 2.2 MB/s | 约 6 条 | 窗口虽小但时延短,单流尚可,调窗口收益有限 |
| 30ms | 1MB | 约 279 Mbps / 35 MB/s | 1 条即超 100M 端口 | 100M 口此时瓶颈在端口,不在窗口 |
| 100ms(近邻区域量级) | 256KB | 约 21 Mbps / 2.6 MB/s | 约 5 条 | 默认缓冲偏保守时的典型表现 |
| 200ms(洲际量级) | 64KB | 约 2.6 Mbps / 0.33 MB/s | 约 38 条(理论值,不现实) | 窗口缩放未生效的典型症状,先查这个 |
| 200ms | 1MB | 约 41.9 Mbps / 5.2 MB/s | 约 3 条 | 调大缓冲后最常见的落点,仍吃不满 100M |
| 300ms(绕路/高峰量级) | 1MB | 约 28 Mbps / 3.5 MB/s | 约 4 条 | 路径绕远或晚高峰排队抬升时,分母变大 |
看完这张表有个直接的用法:拿你测到的单流速度反推一下等效窗口,看看落在哪一行。反推公式就是窗口 ≈ 速度 × 往返时延。如果反推出来的等效窗口只有几十 KB,而你机器上明明配了几 MB,那几乎可以肯定中间有设备把窗口缩放搞坏了,或者有整形在掐。
这是成本最低、收益最直接的一步,改完不用买任何东西。要动的是接收缓冲与发送缓冲的上限(tcp_rmem、tcp_wmem 的最大值那一档),以及整体内存上限(tcp_mem),再确认窗口缩放是开的。给多大按上面那张表倒推:想让单流在 200ms 时延下跑满 100M,窗口就得给到 2MB 上下;想跑满 1G,理论上要 20MB 级别的窗口,这个量级已经要留意内存开销了。
这里有个常被忽略的点:缓冲是双向的,两端都要调。发送端给到 4MB,接收端只通告 64KB,实际生效的还是 64KB。跨境协同的时候,对端常常是别人的机器,这一步得提前沟通好,不然你这边改半天没反应。
还有自动调节。现代内核默认会按连接动态调缓冲,理论上不用手设。但在大时延链路上,这个自动调节的爬升速度未必跟得上短任务的生命周期——传输两分钟就结束了,缓冲还没爬到顶。对长期跑的大文件搬运,手动把上限抬高、下限也抬一抬,往往更省事。
默认的 CUBIC 靠丢包判断拥塞,窗口涨到丢包为止,然后减半、再涨。它的锯齿在大时延链路上恢复得很慢——一个周期就是一个往返,跨境的往返动辄两百毫秒,恢复周期本身就长。
BBR 这类基于带宽与时延建模的算法,不去等丢包,改成探测带宽与最小往返时延,长肥管道上通常表现更好。但要说清楚:它不是万能药。链路本身丢包率高、或者中间设备做深度整形的时候,BBR 的表现未必占优,甚至可能不如调好的 CUBIC。正确的姿势是改完照旧跑一轮单流对比,用数据说话,别迷信名字。
初始拥塞窗口也值得看一眼。很多系统默认十来个报文,意味着每个新连接开头都要花好几个往返才能爬到有效速度。对于大量小文件的同步(几万个碎文件各建一条连接),这个开销会被放大得很夸张。这时候的提速办法往往不是调窗口,而是别建那么多连接。
窗口调到位之后还差一口气,就上并发。两种做法:
多连接:同一个文件开 N 条 TCP 连接各传一段,或者多个文件各占一条。总吞吐近似等于单流乘条数(在带宽没到顶、丢包不严重的前提下)。这是最通用、对应用侵入最小的方式,绝大多数多线程下载工具、分片同步工具干的就是这个。
分片并行:先把大文件切成固定大小的块,多块并行传,到对端再拼回去。跟多连接的区别在于它天然支持断点续传与失败重传——某一块挂了只重传那一块,不用整体重来。跨境传输动辄十几个小时,中断是常态,有没有断点续传基本决定了这个方案能不能真正跑完。
碎文件多的场景要反过来处理:几万个小文件如果一条连接一个地传,握手与慢启动的开销比数据本身还大。先打包、再传、到对端解,往往比任何 TCP 调优都有效。
这类误判特别多。源端读盘慢、目标端写盘慢、校验和计算吃满 CPU、加密没走硬件加速,表现出来都是「传输速度上不去」,跟网络慢长得一模一样。
区分办法:在传输进行中同时看两端的 CPU、磁盘利用率、以及传输进程自己在干什么。如果目标端磁盘一直百分百、写入等待很高,那网络再快也没用。上一篇文章里讲过的 await 与队列深度那套判据,在这里照样能用。
顺序读写和随机读写在这件事上差得远。同一个备份包,源端是连续大块读,目标端如果落在碎片化的文件系统上、或者开了同步写加实时校验,写入速度可能只有读取的一半。媒资文件尤其明显,单个文件几十 G,写进去的时候文件系统还在做块分配。
同样的丢包率,放在同城链路上可能只是偶尔抖一下,放到跨境链路上就是灾难级的。原因在恢复速度,不在丢包本身。
TCP 把丢包当成拥塞信号,一旦判定丢包就把窗口砍下来。砍完之后要重新爬回去,而爬升的节奏是按往返周期计的:一个往返确认一批,窗口才涨一点。往返时延 10ms 的链路,一秒钟能走一百个往返,恢复很快;往返时延 200ms 的链路,一秒钟只有五个往返,恢复慢二十倍。窗口越大,要爬回去的台阶越多,体感越明显。
重传的代价同样被放大。快速重传还能靠重复确认触发,代价相对小;一旦走到超时重传,发送端要干等一个重传超时时间,这个超时值本身又是按往返时延估算的,跨境链路上的超时值就长。等这么久,窗口早空了,速度直接掉到接近零再慢慢爬。
还有一个纯几何的因素:窗口越大,链路上在飞的数据越多,一次丢包影响的报文数量就越多,触发的重传与乱序重组也越多。你想靠大窗口换速度,同时也放大了丢包的杀伤面积。
理论上有个常用的关系可以拿来做量级判断:吞吐量大致与「报文大小 ÷(往返时延 × 丢包率的平方根)」成正比(这是经典的 Mathis 模型,用于理论估算,实际链路会偏离)。注意那个平方根——丢包率降一个数量级,吞吐才涨三倍左右。反过来讲,跨境链路上哪怕只有千分级的丢包,也会被那个大分母放大成肉眼可见的速度损失。所以在这类链路上,比起把窗口开到天上去,先把丢包压下来往往更划算。
丢包从哪来?跨境出口的收敛与调度、晚高峰的排队、路径上某一跳的缓冲区不够、链路质量本身不稳定。定位用 mtr 这类逐跳探测工具看哪一跳开始掉,看清楚是全程均匀掉还是集中在某一跳。集中在一跳,多半是那台设备的缓冲问题或者策略限速;全程均匀掉,多半是链路质量或者总容量吃紧。这一步的结论直接决定后面该换路径还是该加并发。
这是我最常看到的一种「优化」:一上来开 64 条、128 条,理由是反正单条慢。结果总吞吐没涨多少,抖动倒是涨了,还把对端拖出问题。
并发往上堆,会撞上这么几堵墙:
排队时延。条数越多,越容易把链路的缓冲队列填满。队列一满,排队时延就上去了,而排队时延是往返时延的一部分——你为了绕过时延开的并发,反过来又把时延抬高了。队列再满一点就开始丢包,触发前面说的那一整套减速。
乱序。多条流走不同的路径或者被不同的队列调度,到达顺序会乱。接收端要重组,乱序严重会触发重复确认,发送端误判为丢包,进入不必要的重传与降窗。这种情况下,多开的流不但没贡献带宽,还在互相拖。
重传放大。一条流丢包,只影响这一条。一百条流同时遇到一次链路拥塞,可能有一半同时丢包、同时降窗、同时恢复——恢复过程里它们又会同时把队列填满,形成下一轮拥塞。这种同步震荡在大规模并发下非常典型,表现就是吞吐曲线呈周期性塌陷。
落盘随机化。多流并行写同一个大文件的不同片段,对机械盘来说就是把顺序写变成了随机写,速度能掉一个数量级。就算目标是固态盘,过于细碎的并发写入也会影响垃圾回收与写放大。传得过来的数据写不下去,等于白传。
内存与文件描述符。每条连接的发送缓冲与接收缓冲都是实打实的内存。一百条流各配 4MB 缓冲,光缓冲就四百 MB,这还没算应用层自己的读写缓冲。小内存机器上这么开,速度没涨,先开始换页。
对端与中间设备的容忍度。并发过高容易被对端的服务策略、或者中间的安全设备当成异常流量,轻则限速,重则掐断。跨境链路上这种策略更常见。
实操上的做法是从小往大试:4 条起步,每次翻倍,直到总吞吐不再明显增长为止,然后退一档作为常态值。按上面那张表的量级,跨境 200ms 量级、窗口给到位的情况下,个位数到十几条通常就到顶了。需要几十条才能凑够带宽,说明窗口根本没调对——那不该靠并发补,该回去查窗口缩放。
窗口调完、并发试完、丢包也看过之后,如果速度还是不够,或者算下来时间窗口根本塞不下数据量,就该考虑换打法了。四条路,各有各的适用面。
商业的传输加速服务、或者基于 UDP 自研的传输协议,本质上是绕开 TCP 那套「靠丢包判断拥塞、按往返周期爬窗口」的机制,改用更激进的发送策略加前向纠错。在有丢包的长肥管道上,这类方案的提升可以很显著。
但要看清代价:它解决的是传输效率,不是物理定律。窗口与时延的账它一样要算,只是算得更聪明、恢复更快。如果问题是端口本身就那么点带宽,或者链路在晚高峰被整体整形,加速服务也变不出带宽来。它还有个计费问题:通常按流量或按带宽收费的,长期跑大规模同步之前,先拿真实数据量算一笔总账,别只看单次提速比例。
当传输是每天都要跑的、量又稳定的时候,点对点专用线路或者 SD-WAN 这类方案的价值就不是「更快」,而是「可预期」。公网链路的最好时段和最差时段能差很远,做计划的时候你只能按差的那个算,这本身就是成本。租用线路把抖动和丢包压下来之后,前面说的那些调优才真正有意义。
判断标准很实在:如果跨境传输已经进入日常流程(每天一次增量同步、每周一次全量备份),那就值得谈;如果只是偶尔搬一次,公网加调优足够,别为一次性需求签长期合同。
这是我个人最推荐先试的一条路,因为它的逻辑跟前面完全不一样:不去跟跨境链路较劲,而是把长链路拆成两段短链路。
具体做法是:源端把数据传到就近的对象存储(这一段是本地或近邻链路,时延低,容易跑满),然后由存储服务自己做跨区域复制(这一段是服务商的骨干,通常比公网稳定得多),对端再从就近的存储节点拉下来(又是一段短链路)。三段各自都好办,总时间往往比一条跨洋长流直接硬传短得多,而且全程支持断点续传与校验。
对于媒资分发、数据集分发这类「一次上传、多处拉取」的场景,再往前走一步就是 CDN:源站只推一次,边缘节点负责分发。这时候跨境传输这个动作本身就被消掉了——你不再是在两台机器之间搬文件,而是在做一次发布。
要算的是两笔账:存储与跨区域复制的费用、以及上传那一小时与直传十小时的运维价值差。数据量越大、拉取方越多,这条路越划算。
听起来原始,但算完账经常是最优解。判据就是一个除法:数据量 ÷ 你实际能达到的有效吞吐(注意是有效,不是理论),得到小时数。如果这个数大到以天甚至周计,而快递加拷盘的时间是以天计,那物理搬运就赢了。
举一个示例算式:假设 50TB 数据,公网有效吞吐按 5 MB/s 算(纯理论假设值),单流传完要 50×1024×1024 ÷ 5 秒,折合一百多天——这个数字不用再比了。哪怕并发开到八条、有效吞吐到 40 MB/s,也要十几天,而且这十几天里全程占用带宽、随时可能中断重来。这种情况下寄几块盘过去,反而是最省事的选择。
还有几件事要留意:盘的可靠性(别单盘,至少双份)、数据加密(寄送途中不在你手上)、以及清关与时效(跨境寄送有不确定性)。适合的是首次全量迁移这种一次性大动作,日常增量显然不能这么干。
在讨论怎么传得快之前,先问一句能不能传得少。增量同步、去重、压缩、只传变化的部分——这几招的收益往往比调十轮 TCP 参数大得多,而且成本极低。
压缩要算账。跨境带宽贵且慢,压缩省下的传输时间通常值得,但前提是压缩不吃掉 CPU、且数据本身可压缩。已经压缩过的媒资(视频、已经打包的备份)再压一遍基本没收益,纯浪费 CPU。文本类、日志类、数据库导出文件,压缩收益就很大。去重对「每天一份全量备份」这种场景效果最夸张,因为相邻两天的备份大部分内容是一样的。
如果一定要在链路选型上做取舍,节点位置与线路质量比单纯堆带宽更重要——同样标称的端口,走优化回国线路和走普通国际出口,晚高峰的表现可以差很多。像一万网络这种深耕 IDC 19 年(成立于 2007 年)的服务商,在中国香港、美洲、欧洲等多地都有节点,做的是 BGP 多线加 CN2 GIA 回国的线路,真遇到跨境搬运吃力的时候,换个离目标更近的节点、或者选大带宽机型(官网高防大带宽 ¥700 起、美洲 ¥1699 起、欧洲 ¥1299 起,具体以官网实时价为准),往往比在同一台机器上死磕参数有效。
把整套动作排个序,理由也一并写清楚:
第一,算 BDP。拿到往返时延,反推当前等效窗口(速度 × 时延),确认瓶颈确实是窗口,而不是端口、不是磁盘、不是 CPU。这一步不花钱,五分钟能做完。跳过它,后面全是瞎调。
第二,调窗口与缓冲。按目标速度倒推需要的窗口大小,两端一起开,确认窗口缩放没被中间设备破坏。改完跑单流对比,通常这一步就能拿到最大的那一块收益。
第三,查丢包。窗口开大之后丢包的影响也跟着放大,这一步必须在窗口调完之后再做。逐跳看掉在哪,能换路径就换路径。
第四,上并发。从 4 条起步翻倍试,找到不再线性增长的拐点,退一档作为常态。别一上来就几十条。
第五,动应用层。打包碎文件、分片加断点续传、增量与去重。这些跟 TCP 无关,但收益常常更大。
第六,换协议换工具。放在第六位是因为它通常有成本、有绑定,而且前面五步没做完时,你根本不知道换工具到底解决了什么。同样的工具,在窗口没开和窗口开好的链路上,表现完全是两回事。
第七,换路径。点对点专用线路、加速服务、对象存储中转、物理搬运。到这一步就不再是「调优」了,是架构选择,要看数据量、频次、预算一起判断。
这七步里最容易犯错的地方是跳步——尤其是直接跳到第六步和第七步。见过太多次:单流跑不上去就急着买加速服务、急着加带宽,钱花了,问题还在,因为最开始那个几十 KB 的窗口一直没动过。
因为单条 TCP 流的上限是「接收窗口 ÷ 往返时延」,跟端口速率没关系。多线程等于开了 N 条流,每条各占一个窗口,总吞吐就是 N 个窗口除以同一个时延,自然涨上来了。看到「多线程能跑满、单线程很慢」这个现象,几乎可以直接断定瓶颈在窗口与时延,不在带宽。反过来说,这也意味着修法有两个方向:把单流的窗口开大,或者干脆多开几条。前者更优雅,后者更通用,实际通常是两个一起做——先把窗口开到合理值,剩下的差距用少量并发补。
常见四个原因。一是只改了一端,对端通告的窗口还是老样子,实际生效的是两边里小的那个。二是窗口缩放选项在路径上被中间设备破坏了,本机参数看着全对,抓包看握手里的缩放因子才知道真假。三是应用自己设置了 socket 缓冲,覆盖了内核的自动调节,你改内核参数它压根不看。四是压根不是窗口问题——磁盘写不动、端口被限速、链路丢包严重,这几种情况下窗口开再大也没用。判据很简单:改完之后用 ss -i 看这条连接的拥塞窗口到底长到多少了。cwnd 没动,说明改的没生效;cwnd 涨了但速度没涨,说明瓶颈在别处。
两层原因。一是 TCP 把丢包当作拥塞信号,一丢就降窗,而恢复窗口的节奏是按往返周期计的。往返时延 10ms 的链路一秒能走一百个往返,恢复很快;往返时延 200ms 的链路一秒只有五个往返,同样的降窗要花二十倍的时间才爬回来。二是窗口越大,链路上在飞的数据越多,一次丢包波及的报文也越多,重传与乱序重组的开销跟着放大。理论上吞吐大致与丢包率的平方根成反比(Mathis 模型,用于理论估算),也就是说丢包率改善一个数量级,吞吐才涨三倍左右——可见跨境链路上压丢包的优先级有多高。定位办法是逐跳探测,看掉包集中在哪一跳还是全程均匀。
不是,而且开过头会倒扣。并发上去之后会撞上几堵墙:多条流把链路队列填满,排队时延抬高,把你想绕开的时延又加回来了;多路径调度带来乱序,触发不必要的重传与降窗;大量流同时遭遇拥塞会产生同步震荡,吞吐曲线周期性塌陷;并行写同一文件的不同片段会把顺序写变成随机写,机械盘上能掉一个数量级;每条连接的缓冲都是实打实的内存,上百条各配几 MB 就是几百 MB。合理做法是从 4 条起步、翻倍试,找到总吞吐不再线性增长的拐点后退一档。如果需要几十条才凑够带宽,那说明窗口没调对,该回去查窗口缩放而不是继续加并发。
要看它解决的是哪一层。如果工具做的是多连接、分片、断点续传这一类事情,那它确实有效,但这些事你自己用并发与分片也能做到,工具的价值在于省事与稳定。如果它做的是换协议(比如基于 UDP 的自研传输、前向纠错、更激进的拥塞策略),那它在有丢包的长肥管道上确实能拿到 TCP 拿不到的东西。但它改变不了物理时延,也变不出不存在的带宽:端口就那么大,或者链路在晚高峰被整体整形,换什么工具都一样。所以工具该排在窗口、丢包、并发都处理完之后再考虑,那时候你才知道剩下的问题到底是什么,也才知道这个工具值不值那个钱。
三个信号。一是算完账发现时间根本不够:数据量除以你实际能达到的有效吞吐,得到的天数已经超过业务能等的上限,这时候加并发也补不回来。二是传输已经日常化:每天都得跑一次全量、每次都要人盯着重试,说明公网的不确定性已经变成了一个持续成本,点对点专用线路的可预期性本身就值钱。三是数据形态适合中转:一次上传、多处拉取的分发类需求,走对象存储加 CDN 根本不是在「传文件」,而是在「发布」,跨境这一段被拆掉了。还有一个特殊但很现实的情况——首次全量迁移,几十 TB 级别的冷数据,物理搬运大概率比任何网络方案都快。
不是。缓冲的作用是填满管道,给到 BDP 的量级就够了,再往上给没有额外收益。给太大反而有副作用:每条连接都按上限预留内存,连接一多内存就吃紧;缓冲过大还会掩盖真实的拥塞信号,让排队时延悄悄涨上去却不触发降窗,表现为时延抖动变大、交互类流量发涩。合理做法是按目标速度倒推:窗口 ≈ 目标吞吐 × 往返时延,再留一点余量。传大文件的连接可以按这个值给足,同一台机器上跑的大量短连接则不应该共用这个上限。记得区分接收缓冲与发送缓冲——发送端要能装下在飞的数据,接收端要能接住突发,两边通常给同样的量级。
因为公网链路的可用带宽与时延是随时间变的。晚高峰时段跨境出口收敛比高、队列排队长,表现为往返时延抬高、丢包变多,而这两项正好是单流吞吐公式里的分母和破坏项——分母变大速度直接掉,丢包变多又让降窗恢复更频繁。链路容量在高峰期被整体整形的话,加并发也不会有线性收益。这不是玄学,用逐跳探测在高峰和低峰各测一轮,对比排队时延和丢包位置就能看出来。应对办法有几种:把大批量传输排到低峰时段、给传输任务做限速以免在高峰期抢带宽影响线上业务、或者干脆错峰加上断点续传跑满一整晚。能不能这么做取决于业务窗口,能不能真的改善取决于你那条链路的瓶颈到底在出口还是在全程。
跨境传大文件这件事,绝大多数人第一反应是带宽不够,第二反应是买更快的机器或者更贵的线路,真正的原因却常常是一个几十 KB 的窗口和一个两百毫秒的时延在做除法。这个除法的答案摆在单流速度上,跟端口标多少一点关系都没有。
所以我的建议一直没变:先花五分钟把这个除法算出来,再决定要不要花钱。窗口开对、丢包看清、并发试到拐点,这三步走完还不行,才轮到工具与线路。顺序反了,钱花出去连个响都听不到。
顺带提醒一句容易被忽略的:跨境链路是共享资源,别人的高峰期就是你的低峰期,今天调好的参数不代表下个月还一样。真正稳定的做法是把传输做成可中断可续传、把吞吐做监控、把触发线定下来,而不是指望一次调优一劳永逸。
文中涉及的往返时延、窗口大小、单流吞吐与并发条数均为理论计算示例,用于说明量级关系,非任何真实链路的实测数据,请勿直接用于容量承诺。端口速率按常见标称值做参照换算。一万网络节点、线路与价格信息引自官网公开页面(官网明示档:高防大带宽 ¥700 起、美洲 ¥1699 起、欧洲 ¥1299 起、中国香港自营 E3 10M CN2 ¥1500/月),具体以签约时最新报价与合同为准。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品