rsync文件同步:从备份到迁移的瑞士军刀

搞运维这些年,rsync用得比cp多得多。

增量同步、断点续传、压缩传输,这些特性让它在文件传输场景下几乎无可替代。


为什么用rsync

先看个场景:要把100G的日志目录从A服务器同步到B服务器。

用scp:

bash 复制代码
scp -r /data/logs/ user@B:/data/logs/
# 每次都是全量传输
# 中断了要从头来
# 100G传几个小时

用rsync:

bash 复制代码
rsync -avz /data/logs/ user@B:/data/logs/
# 只传有变化的文件
# 中断了从断点继续
# 传输时压缩,省带宽

第一次可能都是100G,但后续同步可能只要传几百M变化的文件。这就是增量同步的威力。


基础用法

本地同步

bash 复制代码
# 基本格式
rsync [选项] 源目录 目标目录

# 同步目录
rsync -av /data/source/ /data/dest/

# 注意:源目录末尾的斜杠很重要!
rsync -av /data/source/ /data/dest/   # 同步source下的内容到dest
rsync -av /data/source /data/dest/    # 同步整个source目录到dest下

斜杠的区别

bash 复制代码
# 有斜杠:同步目录内容
rsync -av /data/logs/ /backup/logs/
# 结果:/backup/logs/下直接是文件

# 没斜杠:同步整个目录
rsync -av /data/logs /backup/
# 结果:/backup/logs/logs/下才是文件(多了一层)

这个坑我见无数人踩过,记住:通常用有斜杠的写法

远程同步

bash 复制代码
# 推送:本地到远程
rsync -avz /data/logs/ user@remote:/data/logs/

# 拉取:远程到本地
rsync -avz user@remote:/data/logs/ /data/logs/

# 指定端口
rsync -avz -e "ssh -p 2222" /data/ user@remote:/data/

常用选项

bash 复制代码
-a, --archive    # 归档模式,等于 -rlptgoD,保持权限、时间等
-v, --verbose    # 详细输出
-z, --compress   # 传输时压缩
-P               # 等于 --progress --partial,显示进度+支持断点续传
-n, --dry-run    # 模拟运行,不实际执行
--delete         # 删除目标中源没有的文件
--exclude        # 排除文件
--include        # 包含文件
--bwlimit        # 限制带宽

推荐组合

bash 复制代码
# 日常同步
rsync -avzP /source/ /dest/

# 镜像同步(目标完全等于源)
rsync -avz --delete /source/ /dest/

# 首次大量传输(显示进度,支持断点)
rsync -avzP --progress /source/ user@remote:/dest/

排除和包含

排除文件

bash 复制代码
# 排除单个目录
rsync -avz --exclude='logs' /data/ /backup/

# 排除多个
rsync -avz --exclude='logs' --exclude='tmp' --exclude='*.log' /data/ /backup/

# 用排除文件
rsync -avz --exclude-from='exclude.txt' /data/ /backup/

# exclude.txt 内容:
logs/
tmp/
*.log
*.tmp
.git/
node_modules/

包含和排除组合

bash 复制代码
# 只同步特定类型文件
rsync -avz --include='*.conf' --exclude='*' /data/ /backup/

# 同步目录结构+特定文件
rsync -avz --include='*/' --include='*.log' --exclude='*' /data/ /backup/

规则是按顺序匹配的,第一个匹配的规则生效。


删除选项

bash 复制代码
# --delete: 删除目标中多余的文件
rsync -avz --delete /source/ /dest/
# 如果源中删了文件,目标也会被删

# --delete-before: 先删除再传输(默认)
# --delete-during: 边传边删
# --delete-after: 传完再删

# 小心使用!建议先 --dry-run 看看会删什么
rsync -avzn --delete /source/ /dest/

实战场景

1. 定时备份

bash 复制代码
#!/bin/bash
# backup.sh

DATE=$(date +%Y%m%d)
SRC="/data/app/"
DEST="/backup/app/"
LOG="/var/log/backup.log"

echo "=== Backup started at $(date) ===" >> $LOG

rsync -avz --delete \
    --exclude='logs/' \
    --exclude='tmp/' \
    --exclude='*.pid' \
    "$SRC" "$DEST" >> $LOG 2>&1

if [ $? -eq 0 ]; then
    echo "Backup completed successfully" >> $LOG
else
    echo "Backup failed!" >> $LOG
    # 发告警
fi

echo "=== Backup finished at $(date) ===" >> $LOG

加入crontab:

bash 复制代码
# 每天凌晨2点备份
0 2 * * * /opt/scripts/backup.sh

2. 跨服务器迁移

bash 复制代码
# 大量数据迁移,限速避免影响业务
rsync -avzP --bwlimit=50000 /data/ user@newserver:/data/
# --bwlimit=50000 表示限速50MB/s

# 迁移完验证
rsync -avzn /data/ user@newserver:/data/
# 如果输出为空,说明完全一致

3. 增量备份到多版本

bash 复制代码
#!/bin/bash
# 保留7天备份

DATE=$(date +%Y%m%d)
SRC="/data/app/"
DEST_BASE="/backup/app"
LATEST="$DEST_BASE/latest"
BACKUP="$DEST_BASE/$DATE"

# 硬链接方式增量备份
rsync -avz --delete --link-dest="$LATEST" "$SRC" "$BACKUP"

# 更新latest链接
rm -f "$LATEST"
ln -s "$BACKUP" "$LATEST"

# 删除7天前的备份
find "$DEST_BASE" -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;

--link-dest 是个神器:如果文件没变化,直接硬链接到上一版本,不占空间。这样保留7天备份,实际占用空间只比一份稍多一点。

4. 双向同步(慎用)

bash 复制代码
# 先A到B
rsync -avz --update /data/shared/ user@B:/data/shared/

# 再B到A
rsync -avz --update user@B:/data/shared/ /data/shared/

# --update 只同步更新的文件,避免覆盖

双向同步容易出问题,生产环境建议用专门的同步工具(如Syncthing)或者确定好主从关系。

5. 断点续传大文件

bash 复制代码
# 传输大文件,中途断了可以继续
rsync -avzP --partial largefile.tar.gz user@remote:/data/

# --partial 保留传了一半的文件,不删除
# -P 等于 --partial --progress

rsync daemon模式

除了SSH,rsync还可以以守护进程方式运行,适合内网大量机器同步。

服务端配置

bash 复制代码
# /etc/rsyncd.conf
uid = nobody
gid = nobody
use chroot = no
max connections = 10
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid

[data]
path = /data
comment = Data directory
read only = no
list = yes
auth users = syncuser
secrets file = /etc/rsyncd.secrets

[backup]
path = /backup
comment = Backup directory
read only = yes
bash 复制代码
# /etc/rsyncd.secrets
syncuser:yourpassword
bash 复制代码
# 权限要设对
chmod 600 /etc/rsyncd.secrets

# 启动
rsync --daemon
# 或者用systemd
systemctl start rsyncd

客户端连接

bash 复制代码
# 格式:rsync://user@host/模块名/路径
rsync -avz syncuser@192.168.1.100::data/ /local/data/

# 或者
rsync -avz rsync://syncuser@192.168.1.100/data/ /local/data/

# 密码可以写文件或环境变量
export RSYNC_PASSWORD="yourpassword"
rsync -avz syncuser@192.168.1.100::data/ /local/data/

daemon模式的好处是不走SSH,配置灵活,适合内网批量同步场景。


性能优化

压缩策略

bash 复制代码
# 已压缩的文件不要再压缩
rsync -avz --compress-level=9 /data/ /backup/  # 压缩级别0-9

# 跳过已压缩格式
rsync -avz --skip-compress=gz/jpg/mp4/zip/rar /data/ /backup/

大量小文件

bash 复制代码
# 大量小文件时,可以先打包
tar czf - /data/logs/ | ssh user@remote "tar xzf - -C /backup/"

# 或者用rsync的 --whole-file 选项
rsync -avz --whole-file /data/ /backup/
# 小文件用whole-file直接传比增量计算快

限制资源

bash 复制代码
# 限制带宽(KB/s)
rsync -avz --bwlimit=10000 /data/ user@remote:/data/

# 限制IO优先级
ionice -c2 -n7 rsync -avz /data/ /backup/

常见问题

1. 权限问题

bash 复制代码
# 保持原权限
rsync -avz /data/ /backup/

# 不保持权限(用目标系统默认)
rsync -rltz /data/ /backup/

# 改变属主
rsync -avz --chown=www:www /data/ /backup/

2. 符号链接

bash 复制代码
# 默认 -a 会复制软链接本身
rsync -avz /data/ /backup/

# 复制软链接指向的文件
rsync -avzL /data/ /backup/

# 跳过软链接
rsync -avz --no-links /data/ /backup/

3. 校验数据完整性

bash 复制代码
# 用校验和对比,更准确但更慢
rsync -avzc /data/ /backup/
# -c 使用checksum而不是时间+大小

# 验证同步结果
rsync -avzn --checksum /data/ user@remote:/data/

4. 空目录

bash 复制代码
# rsync默认不创建空目录(没文件可同步)
# 加 -d 选项
rsync -avzd --include='*/' --exclude='*' /data/ /backup/

与其他工具对比

场景 推荐工具
单次传文件 scp
增量同步 rsync
实时同步 lsyncd (rsync+inotify)
相关推荐
Java水解2 小时前
Spring Boot Starter自定义开发 构建企业级组件库
spring boot·后端
用户617433273102 小时前
访问Windows共享目录
后端
掘金酱2 小时前
2025年度稀土掘金影响力榜单发布!
前端·人工智能·后端
程序员侠客行2 小时前
Mybatis二级缓存实现详解
java·数据库·后端·架构·mybatis
源码获取_wx:Fegn08952 小时前
基于springboot + vue健康茶饮销售管理系统
java·vue.js·spring boot·后端·spring
雅俗共赏zyyyyyy2 小时前
SpringBoot集成配置文件加解密
java·spring boot·后端
计算机学姐3 小时前
基于SpringBoot的送货上门系统【2026最新】
java·vue.js·spring boot·后端·mysql·spring·tomcat
算法与双吉汉堡3 小时前
【短链接项目笔记】6 短链接跳转
java·开发语言·笔记·后端·springboot
飞浪3 小时前
告别“Hello World”:一个有经验的程序员如何用 FastAPI 打造生产级后端模板
后端