Rsync 增量备份
我最早一直在使用 FileZilla 从 Windows 向云服务器传输文件。后来装了本地服务器后,需要发送的文件越来越多,嫌 FileZilla 实在不方便管理,就学会使用了 Samba。
再后来有了两台服务器,Samba 虽然可以在两个 Linux 之间传输数据,但是要经过一次 Windows 电脑,那岂不是传个文件还得用三台电脑。
然后就去学了使用 Syncthing。但我需要的是实际是备份数据,而 Syncthing 的核心是实时同步,其性能过剩且在备份时并没有那么舒适。
再然后就琢磨了一阵子知道了用 scp,不过 scp 是全量备份的。最后发现了 rsync,妥妥的增量备份神器。
安装 Rsync
在 Ubuntu server 系统默认已经配置了 rsync,可用以下命令查看:rsync --version
如果没有,则直接安装即可:sudo apt-get update && sudo apt-get install rsync
使用步骤
假如我要把 A 服务器 (192.168.5.89) 下的 /home/ubuntu/mount0/Resources
文件夹里所有文件增量同步到 B 服务器 (192.168.5.99) 下的 /home/ubuntu/mount1/Resources
目录里。那么同步的配置步骤为:
- 配置密钥。由于我所有服务公用一个密钥,所以只需要把公钥复制到 B 服务器
~/.ssh/authorized_keys
目录上。然后将私钥放在自己指定的位置。我放在/home/ubuntu/.ssh/wang.pem
。 - 在传输数据之前,最好先用
-n
参数测试一下如果要进行传输会有哪些数据将被增量备份。-n
参数使得这次运行是模拟的,不会真实发生。这里值得一提的是,我们的在输入目录路径时,源目录后需要加一个斜杠/
。如果不加这个斜杠,则本次同步会在 B 服务器的 Resources 的下面新建一个 Resouces,然后把 A 服务器传过来的数据放在后面这个 Resouces 子文件夹里,这不是我想要的,我刚使用时就犯了这个错误。
rsync -anvh --delete \
--no-perms --no-owner --no-group \
-e "ssh -i /home/ubuntu/.ssh/wang.pem" \
/home/ubuntu/mount0/Resources/ \
root@192.168.5.99:/home/ubuntu/mount1/Resources/
如果显示为以下情况,则说明没有需要增量备份的数据。需要备份的数据会在输出中显示出来具体的目录。--no-perms --no-owner --no-group
命令用于跳过权限检查。权限是个大坑,如果不跳过权限检查,稍微改一下权限就要全量备份。
❝使用
--no-perms --no-owner --no-group
命令后,接收文件的服务器将保留接收者的权限。❞
sending incremental file list
sent 283,965 bytes received 423 bytes 189,592.00 bytes/sec
total size is 152,041,860,132 speedup is 534,628.25 (DRY RUN)
- 如果增量同步没有问题,则按照以下命令直接执行。
rsync -avh --delete \
--no-perms --no-owner --no-group \
-e "ssh -i /home/ubuntu/.ssh/wang.pem" \
/home/ubuntu/mount0/Resources/ \
root@192.168.5.99:/home/ubuntu/mount1/Resources/
后续备份时只需执行 2 和 3 步即可。
参数说明
rsync 的参数非常多,我一般也用不了几个,具体可参考
- rsync 用法教程。
- rsync 介绍和配置自动同步。
我使用过多参数如下:-r # 递归同步, 即目录下得所有子目录和文件都同步
-a # 归档模式, 除代替 -r 外,还可以同步元信息, 如修改时间、权限等
-v # 会在终端输出详细的信息
-n # 模拟模式
-z # 压缩模式,它会在数据发送到目标机器时进行压缩, 但到了目标机器还是会释放
--no-perms --no-owner --no-group # 跳过权限
--delete # 删除覆盖
-h # 以人类可读的格式输出数字
一般在模拟传输时我使用 -anv
,在正式备份时使用 -av
即可。
排除文件夹 --exclude
rsync 可以排除指定的文件目录不参与备份。
比如我要将 /home/ubuntu/mount0/ 目录中,除 StableDiffusion 目录以外的其他目录备份到 /home/ubuntu/mount0/Docker_backup 目录,则命令应写为:rsync -anv --delete \
--no-perms --no-owner --no-group \
--exclude 'StableDiffusion' \
/home/ubuntu/mount0/ \
/home/ubuntu/mount1/Dcoker_backup/ \
>> /home/ubuntu/mount1/rsync.log 2>&1
另外,如果需要排除的文件夹比较多,也可以将这些文件夹的名称写入一个文件中,然后使用 --exclude-from 来指定这个文件。例如:echo '要排除的文件夹1' > exclude.txt
echo '要排除的文件夹2' >> exclude.txt
rsync -av --exclude-from='exclude.txt' source/ 目标目录/
定时自动备份
在中文互联网找了一圈,似乎大部分文章都是用 rsync 来实现实时同步。这和我的需求不符。我要实时同步那就用 syncthing 就可以了。
我的需要是每隔一段时间比如一周让两台 Linux 服务器自动增量备份一次。因此使用 crontab 再合适不过了。具体步骤如下:
- 在 A 服务器编辑 cron 表。
crontab -e
- 如果要在每天的 13 点 10 分进行增量备份操作,则增加内容如下:
10 17 * * * rsync -anv --delete --no-perms --no-owner --no-group -e "ssh -i /home/ubuntu/.ssh/wang.pem" /home/ubuntu/mount0/Resources/ root@192.168.5.99:/home/ubuntu/mount1/Resources/ >> /home/ubuntu/mount0/rsync.log 2>&1
由于自动备份的情况未知,所以本命令后面增加了输出日志,确保可以检查备份情况。