CentOS 7 和 CentOS Stream 的运维环境里,数据安全始终是悬在头顶的一把剑。很多运维人员习惯用 tar 配合 cron 做全量备份,但面对每天增长几十GB的日志、数据库文件或者用户上传的媒体资源,全量备份会迅速耗尽磁盘 IO 和存储空间。rsync 的增量备份机制能精准识别文件变化,只传输差异部分,配合硬链接快照技术,可以在不占用额外空间的情况下保留多份历史版本。远程容灾则通过 SSH 隧道将备份数据实时同步到异地机房,即便本地机房发生物理灾难,核心数据依然安全。

rsync 增量传输的核心原理

rsync 不像 scp 那样简单粗暴地复制整个文件,它有一套精妙的差分算法。当源端和目标端建立连接后,rsync 会把目标端文件切成固定大小的数据块,对每个数据块计算两种校验和:一个快速的 32 位滚动校验和用于初步比对,一个强校验和 MD5 或 MD4 用于精确确认。源端收到这份校验和列表后,在自己的文件中滑动比对,找出所有匹配的数据块和不匹配的差异部分,最后只把差异数据推送到目标端。这意味着一个 10GB 的虚拟机镜像文件,如果只修改了 100MB 的配置区域,rsync 实际传输的数据量接近 100MB,而不是整个 10GB。

安装与基础配置

CentOS 系统通常预装了 rsync,如果没有,直接通过 yum 安装即可。服务端和客户端都需要安装,但配置方式不同。服务端一般以守护进程模式运行,适合集中备份多台机器;客户端则通过命令行直接调用,适合单机到单机的同步。安装命令很简单:

yum install -y rsync

服务端需要创建配置文件 /etc/rsyncd.conf,这个文件定义了模块名称、备份路径、访问权限和认证信息。一个典型的生产环境配置如下:

uid = root
gid = root
use chroot = yes
max connections = 10
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log

[backup]
path = /data/backup
comment = Production Backup Module
read only = no
list = yes
auth users = backupuser
secrets file = /etc/rsyncd.secrets
hosts allow = 192.168.1.0/24 10.0.0.100

认证文件 /etc/rsyncd.secrets 里按“用户名:密码”的格式写入,权限必须设为 600,否则 rsync 会拒绝启动。服务端启动命令用 systemctl enable rsyncd 设置开机自启,然后 systemctl start rsyncd 启动守护进程。客户端不需要配置文件,直接在命令行里通过双冒号语法访问服务端模块。

增量备份的实战策略

单纯的 rsync 同步只能保留最新状态,不具备版本回溯能力。真正意义上的增量备份需要结合硬链接快照技术。核心思路是:每次执行备份时,先通过 cp -al 命令把上一次备份的目录树完整复制一份,复制时使用硬链接而非实际拷贝数据,这样瞬间就能创建一份“伪全量”快照,几乎不占用额外磁盘空间。然后 rsync 用 --delete 参数把源端的变化同步到这个新快照里,由于硬链接的特性,没有变化的文件继续保持硬链接共享 inode,发生变化的文件才会被实际写入新数据块。

具体实现脚本如下:

#!/bin/bash
BACKUP_SOURCE="/var/www /etc/nginx /var/lib/mysql"
BACKUP_ROOT="/mnt/backup"
DATE=$(date +%Y%m%d_%H%M)
CURRENT_LINK="$BACKUP_ROOT/current"
SNAPSHOT_DIR="$BACKUP_ROOT/$DATE"

# 如果存在上一次备份,用硬链接复制
if [ -d "$CURRENT_LINK" ]; then
    cp -al "$CURRENT_LINK" "$SNAPSHOT_DIR"
fi

# 执行 rsync 同步,覆盖硬链接中变化的文件
rsync -avz --delete --exclude='*.log' $BACKUP_SOURCE "$SNAPSHOT_DIR"

# 更新 current 软链接指向最新快照
rm -f "$CURRENT_LINK"
ln -s "$SNAPSHOT_DIR" "$CURRENT_LINK"

# 清理 30 天前的旧快照
find "$BACKUP_ROOT" -maxdepth 1 -type d -name "20*" -mtime +30 -exec rm -rf {} \;

这套方案的精妙之处在于:每天产生一个完整目录结构的快照,但 30 天的快照总占用空间只比实际数据多出 30 天内增量变化的部分。运维人员可以随时进入任意日期的快照目录,像操作普通文件一样恢复数据,不需要任何解压或还原步骤。--delete 参数确保目标端严格镜像源端,源端删除的文件在快照中也会被清除,避免备份无限膨胀。

远程容灾的传输优化

跨机房同步面临带宽限制和网络中断风险。rsync 通过 SSH 隧道传输时,可以配合一系列参数大幅提升效率。-z 参数开启传输压缩,对文本类文件效果显著,但如果是已经压缩过的图片或视频文件,压缩反而浪费 CPU,这时应该去掉 -z。--bwlimit 参数限制带宽占用,避免备份流量打满生产环境的出口带宽,例如 --bwlimit=5000 限制为 5MB/s。--partial 参数保留未传完的临时文件,网络断开重连后可以断点续传,避免大文件反复重传。

一个典型的远程容灾命令如下:

rsync -avzP --delete --bwlimit=8000 --partial --exclude='*.log' \
    /data/production/ \
    root@192.168.200.100:/data/backup/production/

-P 参数组合了 --partial 和 --progress,既支持断点续传又显示实时进度。目标地址采用 SSH 协议格式,rsync 会自动调用 SSH 建立加密通道。如果 SSH 端口不是默认的 22,可以用 -e "ssh -p 2222" 指定。对于安全性要求极高的场景,建议在目标服务器配置 SSH 密钥认证,并限制该密钥只能执行 rsync 相关命令,防止被用于其他用途。

自动化调度与监控告警

备份脚本写好后,扔进 crontab 里定时执行是最常见的做法。但生产环境不能只满足于“执行了”,必须确保“执行成功了”。rsync 的退出码有明确的含义:0 表示完全成功,23 表示部分文件传输失败,24 表示源文件在传输过程中消失。备份脚本应该捕获退出码,根据结果发送告警。一个健壮的调度脚本片段:

rsync -avz --delete /data/ source:/backup/
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
    echo "Backup success" | mail -s "Backup OK" admin@example.com
elif [ $EXIT_CODE -eq 23 ]; then
    echo "Partial transfer error, check logs" | mail -s "Backup Warning" admin@example.com
else
    echo "Backup failed with code $EXIT_CODE" | mail -s "Backup Critical" admin@example.com
fi

crontab 的调度频率要根据业务 RPO 来定。核心数据库可以每小时同步一次 binlog,文件服务器可以每 4 小时增量一次。注意避免多个 rsync 实例同时运行,脚本开头用 pidof 或文件锁检测已有实例。另外,rsync 的 --link-dest 参数可以替代 cp -al 的方案,在一条命令里完成硬链接快照的创建和同步,语法更简洁但需要 rsync 2.6.4 以上版本。

大规模场景下的性能调优

当文件数量达到百万级别时,rsync 的默认行为会暴露出性能瓶颈。rsync 在开始传输前需要扫描两端文件列表并计算校验和,文件越多,这个阶段耗时越长。--delete 参数在同步前也会对整个目录树做比对,百万文件级别的删除比对可能耗费数十分钟。优化手段包括:用 --exclude-from 把不需要备份的目录写进文件列表,减少扫描范围;对于日志等滚动写入的文件,用 --ignore-existing 跳过目标端已有的文件;把 rsync 的临时文件目录放到 SSD 上,减少 IO 等待。

文件系统层面的优化同样重要。ext4 和 xfs 在处理大量小文件时表现差异很大,xfs 的 inode 分配策略更适合海量小文件场景。如果备份目录包含数百万个小文件,建议目标端使用 xfs 文件系统。另外,rsync 3.1.0 开始支持 --info=progress2 参数,显示整体传输进度而非单个文件进度,在批量同步时能更直观地了解剩余时间。

安全加固措施

rsync 守护进程模式默认没有加密,数据在网络上明文传输,这在跨公网同步时是不可接受的。强烈建议始终通过 SSH 隧道传输,利用 SSH 的加密通道保护数据机密性。如果必须使用 rsyncd 守护进程,至少配置 hosts allow 限制来源 IP,并用 iptables 做二次过滤。认证密码文件权限必须严格设为 600,所属用户为 root。对于特别敏感的数据,可以在 rsync 传输前用 gpg 对文件加密,目标端收到的是密文,即使存储介质被盗也无法读取。

CentOS 系统默认的 SELinux 策略可能会阻止 rsync 访问某些目录。如果 rsync 报权限错误但普通文件权限正常,检查 SELinux 审计日志:ausearch -m avc -ts recent。临时解决方案是用 setenforce 0 关闭 SELinux 测试,确认问题后通过 semanage 添加策略,而不是永久关闭 SELinux。

灾难恢复演练

备份的最终价值体现在恢复能力上。很多团队备份跑了半年,真到需要恢复时才发现备份数据不完整或者恢复流程有缺陷。建议每季度做一次恢复演练:从远程容灾服务器随机抽取一个历史快照,在隔离环境中完整恢复业务系统,验证数据库一致性、文件完整性和服务启动状态。演练过程记录恢复耗时,作为 RTO 的实测数据。rsync 快照方案的优势在这里体现得淋漓尽致——恢复时直接 cp 或 rsync 回源路径即可,不需要解压、不需要导入导出,恢复速度极快。

增量备份与远程容灾的组合,本质是用最小的存储和带宽成本换取最大的数据安全性。rsync 作为 Linux 生态里最成熟的同步工具,配合硬链接快照和 SSH 加密传输,能够构建一套可靠、可验证、易于恢复的备份体系。这套方案已经在无数生产环境中经过验证,从几十GB的个人项目到几十TB的企业数据,都能稳定运行。