上一篇 下一篇 分享链接 返回 返回顶部

单线程大文件传输仅几Mbps,如何区分物理机网络、磁盘与TCP瓶颈?

发布人:Minchunlin 发布时间:2026-10-06 22:06 阅读量:4

大文件传输长时间停在几 Mbps,会直接拉长备份、数据迁移和文件交付的窗口。如果同一台物理机在另一项测试中接近 1Gbps,首先要确认两项测试是否走同一条路径、使用相同方向和连接数。网卡协商到 1Gbps、内网测速接近 1Gbps、多连接测速接近 1Gbps,分别证明不同的能力,不能直接证明某条单连接文件传输也能达到相同速度。

区分网络、磁盘与 TCP 瓶颈,关键是逐步缩小数据经过的环节:先用不读写业务文件的 TCP 测试观察传输路径,再比较单连接和多连接,随后加入源文件读取、目标文件写入及原有应用。每一步都同步记录两端资源状态,而不是看到“磁盘忙”“CPU 不高”或“有重传”就直接归因。

一、确认症状:到底是哪一段、哪一种传输慢

统一速率单位和测试口径

网卡和带宽通常用 Mbps、Gbps,文件工具则可能显示 MB/s、MiB/s。本文采用十进制口径:

  • 1Gbps = 1000Mbps = 125MB/s,后者是理论换算,不等于实际文件吞吐。
  • 5Mbps = 0.625MB/s;5MB/s = 40Mbps,两者相差 8 倍。
  • MiB/s 使用二进制字节单位,1MiB = 1,048,576 字节。

例如,传输一个十进制 10GB 文件,平均速率为 6Mbps,理论耗时为:

10 × 8 × 1000 ÷ 6 ≈ 13333 秒,即约 3 小时 42 分钟。

若平均有效吞吐达到 1Gbps,理论耗时为 80 秒。真实耗时还受协议开销、启动阶段及存储读写影响。

所谓“能跑满 1Gbps”,还应注明测量位置。网卡计数器统计的流量、TCP 工具统计的数据量和应用统计的文件字节数,不一定采用相同口径。在标准 MTU、链路较干净且端点处理能力充足的环境中,千兆网络的 TCP 有效吞吐常见于约 900~950Mbps,但不能把这个范围作为所有线路的验收标准。

固定一个可复现的观察窗口

至少记录以下信息:

核对项需要确认的内容对判断的影响
传输端点实际发送端、接收端及中间服务避免把内网能力当作跨网能力
流量方向上传慢、下载慢,还是双向都慢出口和入口、两端处理能力可能不同
连接数量一个 TCP 连接,还是多个连接多连接总速率不代表单连接速率
传输阶段刚启动、稳定阶段、接近结束慢启动、缓存和落盘会改变曲线
文件条件大小、位置、冷热缓存、是否动态生成决定是否包含磁盘或数据库访问
同时负载备份、其他下载、磁盘任务排除共享资源争用

“单线程”也要进一步核实:应用只有一个工作线程,不代表只建立一条 TCP 连接;反过来,一个 TCP 连接也可能由多个处理线程参与。网络诊断应先按单 TCP 流比较,应用诊断再按线程和任务结构比较。

后文命令以 Linux 为例,涉及 iproute2、ethtool、sysstat、iperf3、curl 和 fio,使用前应确认工具已安装。示例中的地址、网卡名和文件路径需要替换为实际值。压测会占用网络或存储资源,应在获准的端点和可控时段执行。

二、建立原因树:把“传文件”拆成一条数据链

一次文件传输通常经过:

源文件或数据源 → 发送端应用 → TCP 发送端 → 网络路径 → TCP 接收端 → 接收端应用 → 目标存储。

这条链的稳定吞吐受其中较慢的环节限制,但各环节还会通过缓冲区相互影响。接收端写盘慢,可能最终表现为 TCP 接收窗口收缩;发送端读取慢,则可能表现为网络一直没有被充分利用。

二、建立原因树:把“传文件”拆成一条数据链配图

可以沿下面这棵原因树排查:

分支主要观察依据下一步
物理链路与网络路径协商速率、错误增量、路径差异、方向差异用同端点 TCP 测试确认路径能力
TCP 单流单流与多流差距、RTT、拥塞窗口、重传判断时延、丢包、窗口或单流策略
磁盘与文件系统文件读取和写入速率、延迟、队列隔离源端读取与目标端落盘
CPU 与内存单核利用率、线程状态、换页、软中断查加密、压缩、复制和缓冲压力
服务与应用TCP 测试正常,但原应用慢查限速、协议请求流水线及处理逻辑
数据库或动态数据源文件需要实时查询、拼接、导出分别测生成阶段和传输阶段

可引用的判断规则:多连接能接近带宽上限,只说明路径在该测试条件下具备相应的聚合吞吐;它不能排除单流 TCP、单核处理、应用限速或文件读写瓶颈。

三、先排网络与 TCP:不让业务文件干扰判断

检查本机链路,但不要止步于“1000Mb/s”

先确认业务流量实际走哪块网卡:

ip route get 192.0.2.20
ip -s link show dev eno1
ethtool eno1
ethtool -S eno1

重点查看协商速率、双工状态,以及测试前后错误和丢弃计数是否增长。ethtool -S 的统计项名称由驱动决定,应结合网卡说明判断。

这里有两个边界:

  • Speed: 1000Mb/s 只说明本机接口的协商状态,不代表交换机上联、跨网路径和远端出口也有同等余量。
  • 非零错误计数可能来自历史事件;只有在慢传输期间持续增长,才更值得沿网卡、线缆、交换机端口继续追查。

丢弃也不全是物理故障:接收队列不足、系统处理不及时同样可能造成丢包。需要结合 CPU、软中断和队列状态判断。

用同一对端点比较单流、多流和反向

在接收端启动测试服务:

iperf3 -s

在发送端依次执行:

iperf3 -c 192.0.2.20 -P 1 -t 30
iperf3 -c 192.0.2.20 -P 4 -t 30
iperf3 -c 192.0.2.20 -P 1 -t 30 -R

默认方向是客户端向服务器发送,-R 则反向发送。-P 1 表示一个并行测试流,不应将其直接理解为操作系统只有一个线程。

测试服务只应向获准的测试端开放,结束后用 Ctrl+C 停止。不要为了测试而直接放开全部防火墙规则。测试也应尽量复用业务的两端和路由,但不同端口仍可能受到不同策略影响,因此结果不能无条件代替业务流量。

结果组合初步判断继续验证
单流和多流都慢路径容量、共享拥塞或端点处理能力受限看双向差异、错误增量和资源负载
单流慢,多流明显快单流 TCP 或单流处理限制看 RTT、窗口、重传及单核状态
TCP 单流快,文件传输慢路径并非首要怀疑对象转向磁盘、服务和应用
正向慢,反向明显快存在方向性问题对照两端 CPU、接收窗口和出口状态

这些结果是分支入口,不是根因结论。尤其是“多流快”,既可能来自多条连接获得更大的合计窗口,也可能来自连接分散到不同处理资源。

用 RTT 和在途数据解释单流上限

TCP 需要在等待确认时保持足够的数据在途。达到目标速率所需的在途数据量,可按带宽时延积估算:

所需在途字节数 = 目标速率(bit/s)× RTT(秒)÷ 8。

例如,RTT 为 80ms,要达到 1Gbps:

1,000,000,000 × 0.08 ÷ 8 = 10,000,000 字节,即约 10MB。

如果一条连接实际只能维持约 60KB 在途数据,那么仅按窗口与 RTT 的关系估算:

60,000 × 8 ÷ 0.08 = 6,000,000bit/s,即约 6Mbps。

这解释了为什么物理带宽很大,单流仍可能很慢。但 60KB 可能来自接收窗口限制,也可能来自拥塞控制、应用供数不足等原因,不能据此直接修改内核缓冲参数。

两组同样80ms RTT的发送端与接收端示意,分别标出1Gbps目标所需约10MB和60KB实际在途量对应约6Mbps;用数据块与返回确认线解释在途概念,明确不

传输期间可查看连接状态:

ss -tin dst 192.0.2.20

重点观察 rtt、cwnd、mss、重传及窗口相关信息。具体字段随内核和工具版本变化:

  • cwnd 通常以段为单位,可结合 MSS 粗略估算拥塞窗口的字节量。
  • 拥塞窗口和对端通告的接收窗口共同约束发送。
  • rcv_space 不应直接当作对端当前通告的窗口;部分版本显示的 snd_wnd 可提供更直接的参考。
  • delivery_rate 是连接的速率估计,不等于独立测得的线路容量。

应在慢速阶段连续观察,而不是只截取一张状态图。应用没有持续供数时,较小的窗口或较低的速率估计可能是结果,而非原因。

区分丢包、接收背压和路径限制

若重传持续增长、拥塞窗口反复回落,应进一步检查线路丢包、队列拥塞、接口错误或路径 MTU 问题。普通小包 ping 正常,并不能证明大块 TCP 数据传输正常。

反之,如果重传很少,发送端频繁等待接收窗口,而接收端同时出现写盘延迟或应用读取不及时,应优先怀疑接收背压。

还需注意:

  • 中间路由设备对探测报文的限速,可能造成某一跳“丢包高”,但业务流量并未丢失。
  • 大数据传输停滞而小请求正常,可能涉及路径 MTU,但需要相应探测或抓包证据。
  • RTT 随负载明显上升,通常值得检查排队与共享拥塞,但不能只凭 RTT 指定故障设备。
  • 不同端口表现不同,应核对服务和网络策略,而不是立即认定运营商限速。

不要把增大缓冲区、切换拥塞控制或降低 MTU 当成统一答案。先证明问题在哪个分支,再做可回退的单变量调整。

四、再排磁盘与系统:分别观察读取、处理和落盘

同时采集发送端与接收端状态

传输期间,在两端分别观察:

iostat -xz 1 10
mpstat -P ALL 1 10
vmstat 1 10

部分首行是启动以来的平均值,不代表当前一秒,判断时应看后续采样。

磁盘方面,关注吞吐、await、队列和 %util 的联动:

  • 磁盘吞吐接近文件速率,延迟和队列持续增长,说明磁盘分支值得深入。
  • %util 高并不总意味着设备吞吐耗尽,尤其不能机械套用于多队列 NVMe。
  • 网络几 Mbps、块设备几乎没有读写,不能立即认定磁盘没问题:文件可能来自页缓存,也可能位于网络文件系统,需要结合存储类型和应用状态。

CPU 则应按核心观察。一台多核物理机的总 CPU 利用率只有几个百分点,仍可能有一个核心被加密、压缩、校验或协议处理占满。mpstat 能帮助区分用户态处理与软中断压力;进一步可查看对应进程的线程状态。

内存不要只看“空闲多少”。文件缓存占用内存通常是正常现象;持续换页、内存回收压力、脏页积压与吞吐下降同时出现,才更有诊断意义。刚开始很快、随后明显降速,也可能是缓存吸收能力耗尽后暴露了持续写入能力。

先测源文件读取,再隔离目标落盘

若源文件位于支持直接 I/O 的本地文件系统,可在获准时段做只读测试:

fio --name=source-read \
  --filename=/srv/data/large-file.bin \
  --readonly \
  --rw=read \
  --bs=1M \
  --ioengine=psync \
  --iodepth=1 \
  --direct=1 \
  --time_based \
  --runtime=30

该命令只读取指定的现有文件,不应指向原始磁盘或不明路径。即使只读,持续读取也可能影响线上 I/O。

它观察的是单任务顺序读取能力,不完全等同于业务行为。直接 I/O 还可能因文件系统或对齐要求失败;失败只说明测试方式不适用,不能作为磁盘慢的证据。若读取能力为几十或几百 MB/s,而网络传输仅约 0.6MB/s,源端顺序读取通常不是首要瓶颈,但仍需排除业务实际走随机读取、共享存储或其他路径。

对于 HTTP 文件下载,可以把响应写入 /dev/null,暂时去掉接收端文件落盘环节:

curl --fail --silent --show-error \
  --output /dev/null \
  --write-out 'bytes=%{size_download} speed_Bps=%{speed_download} total_s=%{time_total}\n' \
  https://files.example.com/large-file.bin

应替换为获准访问的实际地址,并核对 HTTP 状态和下载字节数,确认收到的是完整文件,而非错误页。speed_download 的单位是字节/秒;乘以 8,再除以 1,000,000,才是 Mbps。该测试仍消耗完整下载流量,也保留了服务端读取、TLS 和客户端接收处理。

可引用的判断规则:同一文件、同一协议、相近负载下,丢弃接收数据明显快于保存文件,才构成目标存储或落盘逻辑受限的线索;如果两者同样慢,应继续检查前面的数据链。

iperf3不读写业务文件;HTTP下载到/dev/null保留源文件读取、HTTP/TLS和接收处理;同一HTTP下载保存文件再加入目标落盘

如果原应用要求每块数据同步落盘,或还包含校验、重命名、远端存储确认,那么普通顺序写入测试不能代表它的端到端速度。

五、定位根因:TCP 快而应用慢,应查什么

排查服务限速和单连接工作量

当单流 iperf3 表现正常、原应用仍只有几 Mbps,重点应转向服务与协议:

  • 服务是否设置按连接、账号、会话或任务的速率限制?
  • 是否在传输过程中做压缩、解压、加密或校验?
  • 是否每发送一块数据,就等待应用层确认后才发送下一块?
  • 是否读取远端文件、实时生成内容,或频繁执行同步落盘?
  • 是否经过反向代理、负载均衡或 CDN,导致两次测试实际走不同路径?

例如,Nginx 的 limit_rate 按响应限速,配置值以字节/秒计。若为 750k,按其单位换算约为 6.144Mbps,可以解释某些接近 6Mbps 的稳定平台。仍需核对生效配置、请求位置及其他限制,不能只凭速度接近便认定命中该设置。

应用层流水线也可能限制吞吐。一个简化示例是:每轮只发送十进制 64KB,等待一次 80ms 确认后再继续,其理论速率约为:

64,000 × 8 ÷ 0.08 = 6.4Mbps。

此时链路、磁盘和 CPU 都可能有余量,真正受限的是应用每轮允许在途的数据量。多线程上传变快,不一定是在修复网络,也可能只是增加了并行请求。

数据库只在实际数据链经过它时排查

传输现成静态文件时,不应因为服务器装有数据库,就把查询性能加入主要原因树。

如果“下载文件”实际上是实时查询、导出和流式发送,则应分别记录查询开始、首字节发出、最后一字节发出及客户端保存完成的时间。首字节等待长,偏向生成阶段;传输中周期性停顿,可能与分批查询、锁等待或应用缓冲有关。

把导出结果预先保存为静态文件后,再走相同下载路径比较,可以帮助区分生成开销与传输开销。相关测试应使用授权数据,不要为排障执行可能影响线上业务的大查询或数据库修改。

用多条证据闭合根因

下面是用于演示判断链的示例组合,并非实际环境测量结果:

示例现象更有支持的判断还需补充的验证
单流约 6Mbps,多流明显更快;RTT 较高,单流在途数据不足单流窗口、拥塞或单流处理限制观察窗口来源、重传和核心负载
单流 TCP 接近链路能力;应用慢且一个核心接近满载应用单核处理受限对照压缩、加密、校验等实际工作
丢弃数据快,保存文件慢;接收端延迟和队列同步上升目标存储或写入逻辑受限对照持续写入与同步落盘要求
读取快、TCP 快,应用稳定停在固定速率服务限速或应用流水线限制核对生效配置和请求行为
正反向 TCP 都慢,接口错误在测试中持续增加本地链路分支可疑对照交换机端口、线缆和网卡统计

可靠的根因判断应同时具备:对应资源或机制的异常、同时间窗口内的关联,以及移除该因素后的改善。只满足其中一项,通常只能称为线索。

六、验证恢复,并留下复发监控点

恢复验证要回到最初的业务路径,而不是只看某项压测变快。保持端点、方向、文件、协议、连接数和负载条件尽量一致,每次只改变一个已经获得证据支持的因素。涉及配置修改时,应先保留原配置、明确影响范围,并准备恢复方法。

验证时建议连续检查:

  1. 单 TCP 流是否改善,多流与单流之间的差距是否符合路径条件。
  2. 原有大文件传输是否在稳定阶段持续改善,而非只在开始几秒变快。
  3. 文件是否完整,校验、落盘和应用完成状态是否正常。
  4. 重传、RTT、磁盘延迟和 CPU 是否出现新的异常。
  5. 同机其他业务是否受到测试或调整影响。

文件要足够大,测试持续时间要足够长,才能暴露缓存耗尽、持续写入、线路波动和应用周期性等待。总平均速率可用于衡量任务耗时,但定位故障还需要速率随时间变化的曲线。

为避免再次出现“只能看到下载慢、无法知道哪里慢”,可保留以下监控:

层级建议监控点主要用途
网络接口收发速率、错误和丢弃增量发现链路及接收处理异常
TCPRTT、重传、窗口和单流吞吐区分路径拥塞与端点背压
存储吞吐、延迟、队列、持续写入状态发现读写瓶颈与缓存后降速
系统各核心利用率、软中断、换页、脏页避免总利用率掩盖局部瓶颈
应用首字节时间、分段速率、任务耗时、限速状态分离生成、传输与落盘阶段

物理机“能跑到 1Gbps”和“单连接传文件只有几 Mbps”可以同时成立。应把前者写清楚测试条件,把后者拆成可重复验证的数据链:同路径 TCP 是否慢,单流为何慢,文件读取是否供得上,接收端是否写得下,应用是否持续发送。这样才能把一次性能现象变成有依据、可验证、可持续监控的根因判断。