Linux 大文件传输方案选型指南 — 五大方案深度对比
来源:运维派 | 发布日期:2026-06-04
问题场景
跨机房同步 GB 级数据库备份、跨地域传输 TB 级日志归档——很多人一上来就 scp 一把梭,结果出现各种问题:100GB 文件传一半网络断了,前面全白传;内网千兆带宽,scp 跑不到 100MB/s;传输完成才发现文件损坏。不同的传输场景需要不同的工具组合。
传输速度的瓶颈通常不是网络带宽,而是:加密开销(SSH 加密消耗 CPU)、磁盘 I/O(源端读取和目标端写入)、网络协议开销(TCP 拥塞控制/窗口大小/重传)、系统参数(socket buffer/tcp 窗口)、文件数量(大量小文件比单一大文件慢得多,每个文件都要打开/关闭/读取元数据)。
五大方案总览
| 方案 | 加密 | 断点续传 | 增量同步 | 多线程 | 内网千兆速度 | 适用场景 |
|---|---|---|---|---|---|---|
| rsync | ✅ SSH | ✅ | ✅ 增量之王 | ❌ | 70-110 MB/s | 定期同步、增量备份、生产首选 |
| scp / sftp | ✅ SSH | ❌ 弱 | ❌ | ❌ | 80-120 MB/s | 临时小文件(<1GB) |
| nc + tar | ❌ | ❌ | ❌ | ❌ | 110-115 MB/s 线速 | 内网裸传、磁盘镜像、速度优先 |
| tar + split | 取决于传输工具 | 分块级别 | ❌ | ✅ 并行 | 80-100 MB/s | >100GB 超大文件、网络不稳 |
| curl / aria2 | HTTP/HTTPS | ✅ aria2 最强 | ❌ | ✅ 多线程 | 110-120 MB/s | HTTP 分发、突破单连接限速 |
方案一:scp / sftp(基础 SSH 传输)
最简单,几乎所有 Linux 发行版自带。基于 SSH 协议,适合临时单次传输。
# 基础用法
scp /local/file user@remote:/remote/path/
# 传目录(注意斜杠:加斜杠复制内容,不加复制目录本身)
scp -r /local/dir/ user@remote:/remote/path/
# 指定端口
scp -P 2222 /local/file user@remote:/remote/path/
# 启用压缩(文本文件效果好,已压缩文件无效)
scp -C /local/file user@remote:/remote/path/
# 指定加密算法减少 CPU 消耗
scp -c aes128-ctr /local/file user@remote:/remote/path/
# 限速(单位 Kbit/s,500KB/s = 4000)
scp -l 4000 /local/file user@remote:/remote/path/
优点: 简单、安全、预装。缺点: 无原生断点续传(断了重头来)、单线程、不支持排除文件和增量同步。OpenSSH 8.0 后默认用 SFTP 协议实现。不适合生产环境的大文件传输。
SSH 配置简化: scp 和 rsync 都支持通过
~/.ssh/config配置别名,定义 Host/User/Port/IdentityFile 后直接用别名传输,省去每次写完整连接串的麻烦。
方案二:rsync(增量同步之王)
生产环境最常用的文件同步工具,支持增量传输(只传变化部分)、断点续传、压缩、保留权限。
# 核心用法:归档+压缩+进度+断点续传
rsync -avzP /local/dir/ user@remote:/remote/dir/
# 同步时删除目标端多余文件(使两端完全一致,慎用!)
rsync -avz --delete /local/dir/ user@remote:/remote/dir/
# 限速(单位 KB/s,10MB/s = 10240)
rsync -avz --bwlimit=10240 /local/file user@remote:/remote/path/
# 排除特定文件
rsync -avz --exclude='*.log' --exclude='cache/' /src/ user@remote:/dest/
# 试运行(先看效果再实际执行,强烈推荐)
rsync -avz --dry-run /src/ user@remote:/dest/
增量传输原理
rsync 把文件分成小块(chunk),对每块计算校验和,只传输校验和不同的块。第一次全量传输,后续只传变化部分。在以下场景极其有用:大文件只有少量变化(如日志追加、数据库追加写入);同步大量文件只有部分变化。
daemon 模式(大规模分发)
# 服务端 /etc/rsyncd.conf
uid = nobody
gid = nobody
use chroot = yes
max connections = 10
[backup]
path = /data/backup/
read only = no
auth users = backupuser
secrets file = /etc/rsyncd.secrets
hosts allow = 10.0.0.0/24
# 客户端
rsync -avz rsync://backupuser@<server>/backup/ /local/backup/
SSH 下优化
# 指定加密算法(减少 CPU 消耗)
rsync -avz -e "ssh -c aes128-ctr" /local/file user@remote:/remote/
# SSH ControlMaster 复用连接
# ~/.ssh/config:
# Host *
# ControlMaster auto
# ControlPath /tmp/ssh-%r@%h:%p
# ControlPersist 600
方案三:nc + tar(内网裸传,速度最快)
不经 SSH 加密,直接裸 TCP 传输,在内网可信环境速度接近线速。本质是"管道 + 网络"——和 tar / dd 等流式工具组合使用。
# 场景:内网传输整个目录
# 接收端(目标机器)
nc -l 9999 | tar xzf - -C /local/path/
# 发送端(源机器,配合 pv 显示进度)
tar czf - /local/dir/ | pv -s $(du -sb /local/dir/ | awk '{print $1}') | nc <server_ip> 9999
# 传输磁盘镜像
dd if=/dev/sda bs=4M | nc <server_ip> 9999
# 接收端恢复
nc -l 9999 | dd of=/dev/sda bs=4M
完整的 nc 传输脚本(含进度和参数校验):
#!/bin/bash
# nc_transfer.sh — nc + tar 流式传输
# 用法:./nc_transfer.sh send|receive <port> <path>
set -e
ACTION=$1
PORT=$2
PATH_ARG=$3
if [ -z "$ACTION" ] || [ -z "$PORT" ] || [ -z "$PATH_ARG" ]; then
echo "Usage:"
echo " Send: $0 send <port> <local_path>"
echo " Receive: $0 receive <port> <remote_path>"
exit 1
fi
if [ "$ACTION" = "send" ]; then
echo "Sending $PATH_ARG to remote:$PORT..."
tar czf - "$PATH_ARG" | pv -s $(du -sb "$PATH_ARG" | awk '{print $1}') | nc -l -p $PORT
elif [ "$ACTION" = "receive" ]; then
echo "Receiving on port $PORT to $PATH_ARG..."
nc <REMOTE_IP> $PORT | pv | tar xzf - -C "$PATH_ARG"
else
echo "Unknown action: $ACTION"
exit 1
fi
需加密时:用 ncat 替代 nc,加 --ssl 参数。⚠️ 仅限可信网络,无完整性校验。
方案四:tar + split(超大文件分卷)
单文件 >100GB 时稳定性差,切成小块分别传输。部分块失败只需重传该块,大幅降低失败成本。
# 打包并分卷(每块 1GB)
tar czf - /local/dir/ | split -b 1G - /backup/file_part_
# 生成 /backup/file_part_aa, _ab, _ac ...
# 传输后合并
cat /backup/file_part_* | tar xzf - -C /local/path/
# 完整校验
md5sum /backup/file_part_* > /backup/md5sums.txt
# 传 md5sums.txt 到目标端后
md5sum -c md5sums.txt
并行传输加速
# 4 路并行 scp
ls /backup/file_part_* | xargs -n 1 -P 4 -I {} scp {} user@remote:/remote/backup/
方案五:curl / wget / aria2(HTTP 多协议下载)
在内网目标端快速搭一个 HTTP 服务,源端用 curl/wget 或 aria2 下载。aria2 支持多线程下载,突破单连接限速。
# 目标端快速搭 HTTP 服务(生产环境推荐 Nginx)
cd /data/backup && python3 -m http.server 8080
# aria2 多线程下载
aria2c -x 16 http://example.com/file.tar.gz # 16 线程
aria2c -c -x 16 http://example.com/file.tar.gz # 断点续传 + 多线程
aria2c --max-download-limit=10M http://url/file # 限速 10MB/s
风险提醒:
python -m http.server是单线程的,并发性能差。生产环境推荐用 Nginx 起下载服务,配置 autoindex + sendfile + tcp_nopush 优化性能。另外 HTTP 传输是明文,公网传输建议用 HTTPS。
选型决策树
是否需要加密?
├─ 是 ── scp / rsync over SSH
└─ 否 ── 继续
是否需要增量传输?
├─ 是 ── rsync
└─ 否 ── 继续
是否需要断点续传?
├─ 是 ── rsync / aria2
└─ 否 ── 继续
文件大小?
├─ <1GB ── scp
├─ 1~100GB ── rsync / nc
└─ >100GB ── tar + split 分卷
传输频率?
├─ 单次 ── scp
└─ 多次 ── rsync
多线程需要?
├─ 是 ── aria2 / tar+split+并行
└─ 否 ── 按上面选
性能对比(千兆内网,10GB 压缩文件)
| 工具 | 速度 | CPU 占用 | 备注 |
|---|---|---|---|
| scp | 80-120 MB/s | 高 | SSH 加密限制 |
| rsync over SSH | 70-110 MB/s | 高 | 初次传输和 scp 接近 |
| nc + tar | 110-115 MB/s | 低 | 接近线速 |
| aria2c (16线程) | 110-120 MB/s | 中 | 受 HTTP 服务性能影响 |
最佳实践
完整性校验 — 传输后必须做
# 源端生成校验和
sha256sum file.tar.gz > file.tar.gz.sha256 # 推荐 SHA256
# 传输校验和文件
scp file.tar.gz.sha256 user@remote:/remote/
# 目标端校验
sha256sum -c file.tar.gz.sha256 # 输出 "file.tar.gz: OK" 通过
生产环境自动重试脚本
#!/bin/bash
# rsync_retry.sh — 带自动重试的生产级传输脚本
# 用法:./rsync_retry.sh <src> <dst> [max_retries] [retry_delay]
set -e
SRC=$1
DST=$2
MAX_RETRIES=${3:-5}
RETRY_DELAY=${4:-10}
if [ -z "$SRC" ] || [ -z "$DST" ]; then
echo "Usage: $0 <src> <dst> [max_retries] [retry_delay_seconds]"
exit 1
fi
ATTEMPT=1
while [ $ATTEMPT -le $MAX_RETRIES ]; do
echo "[Attempt $ATTEMPT/$MAX_RETRIES] rsync $SRC -> $DST"
if rsync -avzP "$SRC" "$DST"; then
echo "Transfer succeeded!"
# 传输完成后做完整性校验
SRC_MD5=$(md5sum "$SRC" | awk '{print $1}')
DST_MD5=$(ssh $(echo $DST | cut -d: -f1) "md5sum $(echo $DST | cut -d: -f2)/$(basename $SRC)" | awk '{print $1}')
if [ "$SRC_MD5" = "$DST_MD5" ]; then
echo "MD5 match: $SRC_MD5"
exit 0
else
echo "MD5 mismatch! Retrying..."
fi
else
echo "Transfer failed. Retrying in $RETRY_DELAY seconds..."
sleep $RETRY_DELAY
fi
ATTEMPT=$((ATTEMPT + 1))
done
echo "Failed after $MAX_RETRIES attempts."
exit 1
网络层调优
# /etc/sysctl.d/99-network-tuning.conf
# TCP 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# TCP 拥塞控制(推荐 BBR)
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# 队列
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
# 应用
sysctl -p /etc/sysctl.d/99-network-tuning.conf
磁盘 I/O 优化
# 用 ionice 调整 I/O 优先级
ionice -c2 -n0 tar czf - /local/dir/ | nc <server_ip> 9999
# -c2 best-effort, -n0 最高优先级
# 用 tmpfs 临时中转(减少磁盘 I/O,但占用内存)
mount -t tmpfs -o size=10G tmpfs /mnt/tmp
tar czf - /local/dir/ > /mnt/tmp/file.tar.gz
nc <server_ip> 9999 < /mnt/tmp/file.tar.gz
完整性校验与日志记录
重要传输任务必须记录"开始时间 - 结束时间 - 文件清单 - 校验和 - 操作人"。建议:
- 生产环境用
rsync+ 自动重试脚本 + 完整性校验覆盖 80% 场景 - 极端场景(超大文件、低带宽、高丢包)再用
nc + tar、tar + split、aria2 - 传输脚本纳入版本管理,审计日志归档
命令速查
| 工具 | 常用参数 |
|---|---|
| scp | -P 2222 端口 / -C 压缩 / -c aes128-ctr 加密算法 / -l 4000 限速 Kbit/s / -p 保留属性 |
| rsync | -avzP 归档压缩进度 / --delete 同步删除 / --bwlimit=10240 限速 KB/s / --dry-run 试运行 / --exclude 排除 |
| nc | nc -l 9999 \| tar xzf - 接收 / tar czf - \| nc host 9999 发送 |
| aria2 | -x 16 线程 / -c 断点续传 / --max-download-limit=10M 限速 / -d /data/ 下载目录 |
| curl | -C - 断点续传 / --limit-rate 10M 限速 / --progress-bar 进度条 / -O 保留文件名 |
关联页面
| 页面 | 关联点 |
|---|---|
| scp-rsync-file-transfer | scp 与 rsync 基础用法详解(互补:基础实操 vs 全方案选型) |
| linux-compression-tools-comparison | Linux 压缩工具对比(tar/gzip/bzip2/xz),传输常搭配压缩 |
| linux-essential-commands-reference | Linux 常用命令参考 |
| server-performance-four-dimensions | 服务器性能四维分析法(磁盘 I/O 调优是传输瓶颈之一) |