一、rsync 是什么,为什么同步备份首选它
服务器的数据备份如果只是定期把整个目录打包上传,既费带宽又费时间。rsync(remote sync)是 Linux 下最经典的文件同步工具,核心能力是增量传输:它会把本地与远端文件按"快照 + 校验"对比,只传有差异的块,配合压缩、断点续传、软链保留等特性,是增量备份与异地容灾的事实标准。
对比 cp/scp:cp 无法跨主机、scp 每次都全量传,rsync 既能本地同步也能走 SSH 跨主机同步,还支持排除规则与限速。本文覆盖基础用法、排除规则、SSH 异地备份、自动化定时任务与快照式增量备份,最后给排错清单。
二、安装与基础参数
Debian/Ubuntu 与 CentOS 安装命令不同,两端(源与目标机)都要装:
# Debian / Ubuntu
apt update && apt install -y rsync
# CentOS / Rocky / AlmaLinux
dnf install -y rsync
# 查看版本
rsync --version | head -n 1
最常用的参数组合及含义:
-a 归档模式,等价于 -rlptgoD,保留权限/属主/时间戳/软链等属性
-v 显示传输明细
-z 传输时压缩
-h 人类可读大小
--delete 删除目标端多出来的文件(让两端完全一致,慎用)
--progress 显示进度
--exclude 排除指定路径
--bwlimit=RATE 限速,单位 KB/s
--partial 断点续传(保留未完成的部分文件)
-n 干跑模式(dry-run),先看会传什么再真传
三、本地同步与排除规则
把 /data/www 同步到 /backup/www,排除缓存目录与日志:
rsync -avz --delete --exclude='cache/' --exclude='*.log' \
/data/www/ /backup/www/
# 先干跑一遍看效果
rsync -avzn --delete --exclude='cache/' /data/www/ /backup/www/
几个易错点:
- 源目录结尾的
/表示同步目录内容,不带/会把目录本身放进去,含义完全不同。 --delete与--exclude结合时,被排除的目录在目标端不会被删,符合直觉。- 排除规则里
--exclude='*.log'只在当前层级生效,要全局排除写--exclude='/**/*.log'或用 filter 文件。
规则多了建议写成 filter 文件管理:
cat > /etc/rsync-exclude.txt <<'EOF'
- cache/
- tmp/
- *.log
- .git/
EOF
rsync -avz --exclude-from=/etc/rsync-exclude.txt /data/www/ /backup/www/
四、通过 SSH 做异地增量备份
跨主机同步最稳妥的方式是走 SSH(免密密钥),无需在目标机开 rsync 守护进程:
# 1. 在备份机(目标机)生成密钥,公钥加到被备份机的 authorized_keys
ssh-keygen -t ed25519
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@源机IP
# 2. 测试免密登录
ssh root@源机IP 'hostname'
# 3. 从备份机拉取(pull)或推送(push)均可
# 拉取:备份机执行
rsync -avz --delete -e 'ssh -p 22 -i ~/.ssh/id_ed25519' \
root@源机IP:/data/www/ /backup/www/
# 推送:源机执行
rsync -avz --delete -e 'ssh -p 22' /data/www/ backup@备份机IP:/backup/www/
生产建议:
- 用非 root 的备份账号 + 限权密钥,公钥行前加
command="rsync --server --sender -logDtpre.iLsfxC . /data/www"可把账号锁定为只读同步。 - SSH 端口非 22 时用
-e 'ssh -p 2222'指定,避免改全局 ssh_config。 - 大文件多时加
--partial --append-verify,中断后重跑只传缺失块,不重复劳动。
五、自动化定时同步与失败告警
用 crontab 每天凌晨自动同步,并把输出写日志,失败时发邮件:
# 编辑 crontab
crontab -e
# 每天 02:30 执行,追加日志
30 2 * * * rsync -avz --delete -e 'ssh -p 22' \
/data/www/ root@备份机IP:/backup/www/ >> /var/log/rsync-sync.log 2>&1
# 只保留最近 30 份日志
find /var/log -name 'rsync-sync.log*' -mtime +30 -delete
想失败告警,用 rsync 的 --log-file 加上脚本判断退出码:
#!/bin/bash
# /usr/local/bin/backup.sh
rsync -avz --delete -e 'ssh -p 22' /data/www/ root@备份机IP:/backup/www/ \
--log-file=/var/log/rsync-sync.log
if [ $? -ne 0 ]; then
echo "rsync 同步失败,请检查 $(date)" | mail -s "[告警] rsync backup failed" admin@example.com
fi
记得 chmod +x /usr/local/bin/backup.sh 并先在 crontab 里测试一次。
六、快照式增量备份与恢复演练
单纯 --delete 同步会让误删的源文件从备份里也消失。要做"每天一个完整可回滚快照",用 --link-dest 硬链接方案:
#!/bin/bash
# /usr/local/bin/snapshot.sh:每天生成一个带日期的快照目录
BASE=/backup/snapshots
DATE=$(date +%Y%m%d)
LAST=$(ls -1 $BASE | tail -n 1)
# 第一次全量,之后增量(未变化的文件用硬链接,不占空间)
if [ -z "$LAST" ]; then
rsync -a --link-dest="$BASE/$LAST" /data/www/ "$BASE/$DATE/"
else
rsync -a --link-dest="$BASE/$LAST" /data/www/ "$BASE/$DATE/"
fi
# 只保留最近 7 份
find $BASE -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
这套方案用 --link-dest 把与上一份相同的文件变成硬链接,占用空间几乎为零,却能提供任意一天的历史快照。恢复时直接:
rsync -a /backup/snapshots/20261010/ /data/www/
# 或直接 tar 打包快照目录转移
tar czf restore_20261010.tar.gz -C /backup/snapshots/20261010 .
七、常见排错
1. 报错 rsync: connection unexpectedly closed
多为 SSH 端口、密钥或防火墙问题。先用 ssh -v 目标IP 确认能连上;再确认目标机装了 rsync;最后检查安全组/iptables 是否放行 22 端口。
2. 权限报错 Permission denied (publickey)
检查 ~/.ssh/authorized_keys 权限:目录 700、文件 600,且公钥文件属主正确。用 ls -la ~/.ssh 排查。
3. 同步时磁盘 IO 打满
高峰期同步会抢业务 IO。给 rsync 加 --bwlimit=10240(限 10MB/s)并用 ionice -c2 -n7 rsync ... 降低优先级。
4. --delete 误删数据
任何涉及 --delete 的脚本,第一次运行前必须用 -n(dry-run)检查一遍,且先用一条 --backup 或快照兜底。把 delete 操作包一层确认逻辑更安全。
5. 时间不同步导致跳过文件
源机与目标机时钟偏差大时 rsync 可能误判。装好 chrony 或 ntpdate 保持两端时间一致,再跑 rsync -a --checksum 强制按内容比对。




