问题现象
使用 rsync 同步 TB 级目录(含数百万小文件),命令如下:
bash
rsync -avz --delete --size-only --bwlimit=30M -e "ssh -p 19098" /src/ user@remote:/dest/
同步数小时后随机中断,报错:
lua
rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20)
rsync: write error: Broken pipe (32)
重新运行又从头开始,反复失败,永远无法完成。
原因分析
rsync 默认不保留部分传输的文件。一旦连接中断(SSH 超时、网络闪断),未完成的文件会丢失,下次同步需重新传输该文件。若大文件中断多次,或扫描阶段因小文件过多导致空闲超时,整个任务将陷入死循环。
根本原因:未启用断点续传。
解决方案
同时优化 SSH 保活:
bash
rsync -avz --delete --size-only \
--partial --partial-dir=.rsync-partial \
--bwlimit=30M \
-e "ssh -p 19098 -o ServerAliveInterval=60 -o ServerAliveCountMax=3" \
/src/ user@remote:/dest/
添加 --partial --partial-dir=.rsync-partial 参数。
--partial:保留已传输的文件片段,中断后下次可继续。--partial-dir:指定临时目录存放碎片,避免与完整文件混淆。
其他参数说明:
| 参数 | 作用 |
|---|---|
--partial |
保留部分传输的文件,实现断点续传 |
--partial-dir |
指定碎片目录,避免残留 |
-o ServerAliveInterval=60 |
SSH 保活,防止空闲超时断开 |
--bwlimit |
限速,避免占满业务带宽 |
--size-only |
只比较大小,加快增量扫描 |
效果
中断后重新执行相同命令,rsync 自动从断点继续,不再从头开始。最终成功完成全部数据同步。
附脚本:
bash
#!/bin/bash
# 配置参数 - 按需修改
REMOTE_IP="192.168.0.3"
SSH_PORT="22"
REMOTE_BASE="/remote-backup-dir"
# 待同步的本地源目录列表
SOURCE_DIRS=(
"/minio/source-dir1"
"/minio/source-dir2"
"/minio/source-dir2"
)
# 循环执行 rsync 同步
echo "========== 开始批量目录同步 =========="
for src_dir in "${SOURCE_DIRS[@]}"; do
# 提取目录名,拼接远端目标路径
dir_name=$(basename "${src_dir}")
dest_dir="${REMOTE_IP}:${REMOTE_BASE}/${dir_name}/"
echo -e "\n正在同步: ${src_dir}/ --> ${dest_dir}"
rsync -avz --delete --size-only --partial --partial-dir=.rsync-partial --bwlimit=30M -e "ssh -p ${SSH_PORT}" "${src_dir}/" "${dest_dir}"
# 判断同步结果
if [ $? -eq 0 ]; then
echo "✅ ${src_dir} 同步完成"
else
echo "❌ ${src_dir} 同步失败"
fi
done
echo -e "\n========== 全部同步任务结束 =========="