rsync 优点和不足

rsync 的优点与不足与传统的cp、tar备份方式相比, rsync具有安全性高、备份迅速、支持增量备份等优点,通过 rsync可以解决对实时性要求不高的数据备份需求, 例如,定期地备份文件服务器数据到远端服务器,对本地磁盘定期进行数据镜像等。随着应用系统规模的不断扩大,对数据的安全性和可靠性提出了更高的要求, rsync在高端业务系统中也逐渐暴露出了很多不足。 首先, rsync同步数据时,需要扫描所有文件后进行比对,然后进行差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将是非常耗时的,而且发生变化的往往是其中很少的一部分,因此 rsync是非常低效的方式。其次, rsync不能实时监测、同步数据,虽然它可以通过 Linux守护进程的方式触发同步,但是两次触发动作一定会有时间差,可能导致服务器端和客户端数据出现不一致,无法在出现应用故障时完全恢复数据。基于以上原因, rsync+inotify组合出现了

初识 inotify

inotify是一种强大的、细粒度的、异步的文件系统事件监控机制, Linux内核从2.6.13版本起,加入了对 inotify的支持。通过 inotify可以监控文件系统中添加、删除、修改、移动等各种细微事件,利用这个内核接口,第三方软件可以监控文件系统下文件的各种变化情况, inotify- tools就是这样的一个第三方软件。在上一节中讲到, rsync可以实现触发式的文件同步,但是通过 crontab守护进程方式进行触发,同步的数据和实际数据会有差异,而 inotify可以监控文件系统的各种变化,当文件有任何变动时,会触发 rsync同步,这样刚好解决了同步数据的实时性问题。

1、 安装inotify工具inotify-tools

由于 inotify的特性需要 Linux内核的支持,在安装 inotify-tools前要先确认 Linux系统内核是否是2.6.13版本以上,如果 Linux内核低于26.13版本,就需要重新编译内核加入对inotify的支持。可以用如下方法判断内核是否支持

wang@wang-PC:~$ uname -a
Linux wang-PC 5.4.50-amd64-desktop #3000 SMP Fri Dec 18 18:10:42 CST 2020 x86_64 GNU/Linux
wang@wang-PC:~$ ls -al /proc/sys/fs/inotify
总用量 0
dr-xr-xr-x 1 root root 0 7月  15 08:36 .
dr-xr-xr-x 1 root root 0 7月  15 08:32 ..
-rw-r--r-- 1 root root 0 7月  15 11:41 max_queued_events
-rw-r--r-- 1 root root 0 7月  15 11:41 max_user_instances
-rw-r--r-- 1 root root 0 7月  15 08:36 max_user_watches
wang@wang-PC:~$ 

下载安装inotify-tool

涉及命令: inotifywait # 用于等待文件或文件集上的一个特定事件,可以监控任何文件和目录设置,并且可以递归的监控整个目录树; -m # 表示始终保持事件监听状态 -r # 表示递归查询目录 -q # 表示打印出监控事件 -e # 指定要监控的事件,常用的事件:modify、delete、create、attrib等

inotifywatch # 用于收集被监控的文件系统统计数据,包括每个inotify事件发生多少次等信息;

2、利用rsync+inotify 搭载实时同步系统

案例描述这是一个CMS内容发布系统,后端采用负载均衡集群部署方案,由一个负载调度节点、3个服务节点及一个内容发布节点构成。内容发布节点负责将用户发布的数据生成静态页面,同时将静态网页传输给3个服务节点,而负载调度节点负责将用户请求根据负载算法调度到相应的服务节点上,实现用户访问。用户要求在前端访问到的网页数据始终是最新的、一致的。 解决方案为了保证用户访问到的数据的一致性和实时性,必须保证3个服务节点上的数据与内容发布节点上的数据始终是一致的,这就需要通过文件同步工具来实现,这里采用 rsync。同时又要保证数据是实时的,这就需要 inotify,即利用 inotify监视内容发布节点文件的变化,如果文件有变动,那么就启动 rsync,将文件实时同步到3个服务节点上。 系统环境 image.png

1、安装rsync 与 inotify-tools

节点 rsync inotify
Web1 ×
Web2 ×
Web3 ×
Server

其中Server充当rsync服务端的角色,整个数据同步的过程是一个从客户端向服务器端发送数据的过程。

2、 在三个节点配置rsync

  • Web1节点的rsync.conf
uid nobody
gid= nobody
use chroot = no
max connections = 10
strict modes = yes
pid file = /var/run/rsync.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
[web1]
path = /web1/wwwroot/
comment = web1 file
ignore errors
read only = no
write only = no
hosts allow = 192.168.12.134
hosts deny = *
list = false
uid = root
gid = root
auth users = web1user
secrets file = /etc/web1.pass
    • 创建密码文件
vim /etc/web1.pass
web1user:123.abc
chmod 600 /etc/web1.pass
  • Web2节点的rsync.conf
uid nobody
gid= nobody
use chroot = no
max connections = 10
strict modes = yes
pid file = /var/run/rsync.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
[web1]
path = /web2/wwwroot/
comment = web2 file
ignore errors
read only = no
write only = no
hosts allow = 192.168.12.134
hosts deny = *
list = false
uid = root
gid = root
auth users = web2user
secrets file = /etc/web2.pass
    • 创建密码文件
vim /etc/web2.pass
web2user:123.abc
chmod 600 /etc/web2.pass
  • Web3节点的rsync.conf
uid nobody
gid= nobody
use chroot = no
max connections = 10
strict modes = yes
pid file = /var/run/rsync.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
[web1]
path = /web3/wwwroot/
comment = web3 file
ignore errors
read only = no
write only = no
hosts allow = 192.168.12.134
hosts deny = *
list = false
uid = root
gid = root
auth users = web3user
secrets file = /etc/web3.pass
    • 创建密码文件
vim /etc/web3.pass
web3user:123.abc
chmod 600 /etc/web3.pass
  • rsync守护进程启动并加入自动启动文件中
echo "/usr/local/bin/rsync --daemon" >>/etc/rc.local

3、 配置内容发布节点

配置内容发布节点的主要工作是将生成的静态网页实时同步到集群中3个服务节点上这个过程可以通过一个 shell 脚本来完成。脚本内容大致如下:

#!/bin/bash
host1=192.168.12.131
host2=192.168.12.132
host3=192.168.12.133
src=/web/wwwroot/
dst1=web1
dst2=web2
dst3=web3
user1=webuser1
user2=webuser2
user3=webuser3
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src \
| while read files
do
/usr/bin/rsync -vzrtopg --delete --progress --password-file=/etc/server.pass $src $user1@host1::$dst1
/usr/bin/rsync -vzrtopg --delete --progress --password-file=/etc/server.pass $src $user2@host2::$dst2
/usr/bin/rsync -vzrtopg --delete --progress --password-file=/etc/server.pass $src $user3@host3::$dst3
echo "${files} was rsynced" >>/tmp/rsync.log 2>&1
done

这个脚本的作用就是通过 inotify监控文件目录的变化,进而触发 rsync进行同步操作。由于这个过程是一个主动触发操作的过程,是通过系统内核完成的,所以,比那些遍历整个目录的扫描方式效率要高很多。有时会遇到这样的情况:向 inotify监控的目录(这里是/web/wwwroot/)中写入一个很大的文件,当写入这个大文件需要一段时间时, inotify会持续不停地输出该文件被更新的信息,这样就会持续不断地触发 rsync执行同步操作,占用大量系统资源。针对这种情况,最理想的做法是等待文件写完后再触发 rsync同步。在这种情况下,可以修改 inotify的监控事件,即“- e close write, delete, create, attrib”。接着,将这个脚本命名为 inotifyrsync.sh后放到/web/ wwwroot目录下,然后为其指定可执行权限,放到后台运行。过程如下:

chmod 755 /web/wwwroot/inotifyrsync.sh
/web/wwwroot/inotifyrsync.sh &

将该脚本加入自启动文件: echo "/web/wwwroot/inotifyrsync.sh &">>/etc/rc.local