Rsync 入门:高效同步与镜像备份
Rsync 是 Linux 运维里非常实用的文件同步工具。它既可以在本机目录之间同步,也可以通过 SSH 在不同服务器之间同步。和简单的 cp、scp 相比,rsync 最大的优势是:只传输变化的部分,重复执行时速度更快,也更适合做备份和镜像。
这篇文章记录一套入门用法,重点放在实际工作中最容易用到、也最容易踩坑的部分。
Rsync 适合做什么
常见场景包括:
- 把本地目录同步到备份盘
- 把服务器上的配置文件拉回本地
- 把构建产物发布到远程服务器
- 定时把业务目录镜像到备份服务器
- 配合
--exclude排除日志、缓存、临时文件 - 配合
--delete让目标目录和源目录保持完全一致
一句话概括:如果你需要反复同步一批文件,rsync 通常比手写 cp、scp 更合适。
安装
大多数 Linux 发行版默认已经安装 rsync。可以先检查版本:
rsync --version
如果没有安装,可以按发行版安装:
# Debian / Ubuntu
sudo apt update
sudo apt install rsync
# CentOS / RHEL
sudo yum install rsync
# Fedora
sudo dnf install rsync
Windows 下如果使用 WSL,也可以直接在 WSL 里安装和使用 rsync。
基本语法
rsync 的基本格式如下:
rsync [选项] 源路径 目标路径
最常见的本地同步命令:
rsync -av source/ backup/
这里:
-a表示归档模式,会保留权限、时间、软链接等信息-v表示显示详细输出source/是源目录backup/是目标目录
执行后,source/ 里的内容会同步到 backup/。
尾部斜杠很重要
rsync 里最容易踩坑的是源路径末尾的 /。
带尾部斜杠
rsync -av source/ backup/
表示同步 source 目录里面的内容到 backup/。
同步结果类似:
backup/file.txt
backup/images/logo.png
不带尾部斜杠
rsync -av source backup/
表示把 source 目录本身同步到 backup/。
同步结果类似:
backup/source/file.txt
backup/source/images/logo.png
简单记法:
source/:同步目录内容source:同步目录本身
如果要做镜像备份,大多数情况下用的是 source/。
常用参数
日常使用可以先记住这一组:
rsync -avh --progress source/ backup/
参数说明:
-a:归档模式,保留文件属性-v:显示详细过程-h:用更易读的方式显示文件大小--progress:显示传输进度
远程同步时,经常会加上压缩:
rsync -avz source/ user@server:/data/backup/
参数说明:
-z:传输时压缩数据,适合网络同步
如果是局域网内的大文件传输,-z 不一定更快,因为压缩也会消耗 CPU。是否使用可以按网络和机器性能决定。
先 dry-run 再执行
涉及删除、覆盖、线上目录时,建议先用 --dry-run 看看会发生什么:
rsync -avh --dry-run source/ backup/
--dry-run 只模拟执行,不会真的复制、删除文件。确认输出符合预期后,再去掉这个参数执行真实同步。
也可以写短参数:
rsync -avhn source/ backup/
其中 -n 就是 dry-run。
本地目录同步
比如把 /data/app/uploads/ 备份到 /backup/uploads/:
rsync -avh /data/app/uploads/ /backup/uploads/
如果再次执行,rsync 会比较文件差异,只同步变化过的文件。
如果希望目标目录和源目录保持完全一致,可以加上 --delete:
rsync -avh --delete /data/app/uploads/ /backup/uploads/
注意:--delete 会删除目标目录里源目录不存在的文件。这个参数很适合镜像,但也最危险,正式执行前建议先 dry-run:
rsync -avh --delete --dry-run /data/app/uploads/ /backup/uploads/
通过 SSH 同步远程服务器
rsync 默认可以通过 SSH 连接远程服务器。
把本地目录推送到服务器:
rsync -avz ./dist/ root@example.com:/var/www/html/
把服务器目录拉到本地:
rsync -avz root@example.com:/var/www/html/ ./html-backup/
指定 SSH 端口:
rsync -avz -e "ssh -p 2222" ./dist/ root@example.com:/var/www/html/
指定私钥:
rsync -avz -e "ssh -i ~/.ssh/deploy_key" ./dist/ root@example.com:/var/www/html/
如果远程服务器已经配置了 SSH 免密登录,rsync 就可以很方便地放进脚本或定时任务。
排除不需要同步的文件
同步项目目录时,经常需要排除依赖、缓存、日志和临时文件:
rsync -avh \
--exclude "node_modules/" \
--exclude ".git/" \
--exclude "dist/" \
--exclude "*.log" \
./project/ /backup/project/
排除规则也可以写到文件里:
node_modules/
.git/
dist/
*.log
.env
假设文件名为 rsync-exclude.txt,同步时这样使用:
rsync -avh --exclude-from=rsync-exclude.txt ./project/ /backup/project/
需要注意的是,排除路径一般是相对于源目录的路径。
镜像备份脚本
下面是一个简单的镜像备份脚本,把 /data/app/uploads/ 同步到备份服务器:
#!/usr/bin/env bash
set -euo pipefail
SOURCE="/data/app/uploads/"
TARGET="backup@example.com:/backup/app/uploads/"
LOG_DIR="/var/log/rsync-backup"
LOG_FILE="${LOG_DIR}/uploads-$(date +%F).log"
mkdir -p "${LOG_DIR}"
rsync -avhz --delete \
--exclude "*.tmp" \
--exclude "*.log" \
"${SOURCE}" \
"${TARGET}" \
> "${LOG_FILE}" 2>&1
保存为 backup-uploads.sh 后加执行权限:
chmod +x backup-uploads.sh
手动执行:
./backup-uploads.sh
如果要定时执行,可以配合 crontab:
crontab -e
每天凌晨 2 点执行:
0 2 * * * /opt/scripts/backup-uploads.sh
这种方式得到的是镜像备份:目标目录会尽量保持和源目录一致。优点是恢复简单,缺点是如果源目录误删了文件,下一次同步也会把目标目录里的对应文件删掉。
所以重要数据不要只做单份镜像,最好再加快照或版本保留策略。
使用 link-dest 做增量快照
如果希望保留每天的备份版本,可以使用 --link-dest。它会把没有变化的文件用硬链接指向上一份快照,只有变化的文件才真正占用新空间。
示例目录:
/backup/app/
2026-04-22/
2026-04-23/
2026-04-24/
latest -> 2026-04-24
脚本示例:
#!/usr/bin/env bash
set -euo pipefail
SOURCE="/data/app/uploads/"
BACKUP_ROOT="/backup/app"
TODAY="$(date +%F)"
TARGET="${BACKUP_ROOT}/${TODAY}"
LATEST="${BACKUP_ROOT}/latest"
mkdir -p "${TARGET}"
if [ -L "${LATEST}" ] || [ -d "${LATEST}" ]; then
rsync -avh --delete --link-dest="${LATEST}" "${SOURCE}" "${TARGET}/"
else
rsync -avh --delete "${SOURCE}" "${TARGET}/"
fi
ln -sfn "${TARGET}" "${LATEST}"
这样每天都会生成一个看起来完整的备份目录,但重复文件不会重复占用空间。
使用 --link-dest 时要注意:
- 源路径和目标路径的尾部斜杠要保持清晰
--link-dest最好使用绝对路径- 备份目录所在文件系统需要支持硬链接
- 删除旧快照前先确认不再需要恢复到那一天
从备份恢复
恢复其实也是一次反向 rsync。
从本地备份恢复:
rsync -avh /backup/uploads/ /data/app/uploads/
从远程备份服务器恢复:
rsync -avz backup@example.com:/backup/app/uploads/ /data/app/uploads/
如果恢复目标是线上目录,仍然建议先 dry-run:
rsync -avhn backup@example.com:/backup/app/uploads/ /data/app/uploads/
确认无误后再真实执行。
常见问题
权限不一致
如果需要保留属主和属组,需要用归档模式,并且可能需要 root 权限:
sudo rsync -av /data/app/ /backup/app/
远程服务器如果需要 sudo,可以先同步到用户目录,再在远程服务器上移动,或者配置受控的 sudo 权限。
软链接怎么处理
-a 会保留软链接本身。如果你希望同步软链接指向的真实文件,可以使用 -L:
rsync -avL source/ backup/
但 -L 可能导致同步范围变大,使用前要确认软链接指向哪里。
文件很多时很慢
rsync 在文件数量特别多时,扫描和比较也会耗时。可以考虑:
- 分目录同步
- 排除缓存和临时文件
- 避免跨网络同步大量小文件
- 对长期不变的数据按归档包处理
目标目录空间不足
可以先用 --dry-run --stats 看同步规模:
rsync -avhn --stats source/ backup/
也可以在同步前检查磁盘空间:
df -h
使用前检查清单
正式执行 rsync 前,尤其是带 --delete 时,可以按这个顺序检查:
- 源路径是否正确
- 目标路径是否正确
- 源路径尾部斜杠是否符合预期
- 是否需要排除
.git、日志、缓存、临时文件 - 是否先执行过
--dry-run - 是否确认
--delete不会误删目标目录里的重要文件 - 是否有恢复演练或至少确认备份可读
总结
入门 rsync 可以先掌握这几个命令:
# 本地同步
rsync -avh source/ backup/
# 镜像同步,目标会删除源不存在的文件
rsync -avh --delete source/ backup/
# 先模拟执行
rsync -avhn --delete source/ backup/
# 推送到远程服务器
rsync -avz source/ user@server:/backup/source/
# 从远程服务器拉取
rsync -avz user@server:/backup/source/ ./source-backup/
真正要记住的是两点:
- 不确定时先加
--dry-run - 使用
--delete前一定确认源路径、目标路径和尾部斜杠
把这两点做到,rsync 就是一个非常稳定、高效、值得长期使用的同步和备份工具。