rsync数据同步实战:增量备份、异地容灾与自动化定时同步


一、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 强制按内容比对。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Let's Encrypt证书实战:acme.sh申请、自动续期与泛域名配置

VPS网络加速实战:TCP BBR开启、队列算法与内核参数调优

评 论
更换验证码