rsync+inotify实现数据实时备份

一、rsync简介

 

      rsync是类unix系统下的数据镜像备份工具——remote sync。与传统的cptar备份方式相比,rsync具有安全性高、备份迅速、支持增量备份、本地复制,远程同步等优点,通过rsync可以解决对实时性要求不高的数据备份需求,例如定期的备份文件服务器数据到远端服务器,对本地磁盘定期做数据镜像等。

随着应用系统规模的不断扩大,对数据的安全性和可靠性也提出的更好的要求,rsync在高端业务系统中也逐渐暴露出了很多不足,首先,rsync同步数据时,需要扫描所有文件后进行比对,进行差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将是非常耗时的。而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式。其次,rsync不能实时的去监测、同步数据,虽然它可以通过linux守护进程的方式进行触发同步,但是两次触发动作一定会有时间差,这样就导致了服务端和客户端数据可能出现不一致,无法在应用故障时完全的恢复数据。基于以上原因,rsync+inotify组合出现了!

 

二、inotify简介

 

 Inotify 是一种强大的、细粒度的、异步的文件系统事件监控机制,linux内核从2.6.13起,加入了Inotify支持,通过Inotify可以监控文件系统中添加、删除,修改、移动等各种细微事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools就是这样的一个第三方软件。

在之前章节中,我们讲到,rsync可以实现触发式的文件同步,但是通过crontab守护进程方式进行触发,同步的数据和实际数据会有差异,而inotify可以监控文件系统的各种变化,当文件有任何变动时,就触发rsync同步,这样刚好解决了同步数据的实时性问题。

 

 

三、实时同步和定期同步的优缺点

定期同步的优点:可定时备份,节约CPU资源和带宽资源,

定期同步的不足:执行备份的时间固定,延期明显,实时性差,当同步源长期不变化时,密集的定期任务是不必要的

 

实时同步的优点:一旦同步源出现变化,立即启动备份;只要同步源无变化,则不执行备份。

实时同步的不足:服务器压力较大时,执行实时备份会增加服务器负载。

 

四、先使用rsync实现服务器数据备份

1、安装前的准备工作

主机名

主机IP地址

系统版本

系统内核版本

数据服务器server

192.168.115.120

CentOS 7.x

3.10.0-514.el7.x86_64

备份服务器backup

192.168.115.130

CentOS 7.x

3.10.0-514.el7.x86_64

 

1)两台服务器都关闭防火墙和selinux

[root@backup ~]# systemctl stop firewalld

[root@backup ~]# systemctl disable firewalld

[root@backup ~]# sed -i "7s/enforcing/disabled/" /etc/selinux/config

[root@backup ~]# setenforce 0

 

2)配置数据服务器IP地址为192.168.115.120,备份服务器IP192.168.115.130

2、在备份服务器安装rsync,并创建用户及模块目录并更改其用户组

[root@backup ~]# yum -y install rsync     数据服务器

[root@backup ~]# useradd rsync -s /sbin/nologin -M

[root@backup ~]# grep rsync /etc/passwd

rsync:x:1000:1000::/home/rsync:/sbin/nologin

[root@backup ~]# mkdir /backup     创建rsync daemon工作模式的模块目录

[root@backup ~]# chown rsync.rsync /backup/   更改模块目录的用户组

[root@backup ~]# ll -d /backup/

drwxr-xr-x 2 rsync rsync 6 3   4 13:57 /backup/

 

3、修改rsync daemon配置文件/etc/rsyncd.conf

[root@backup ~]# vim /etc/rsyncd.conf

# /etc/rsyncd: configuration file for rsync daemon mode

# See rsyncd.conf man page for more options.

# configuration example:

uid = rsync                 设置rsync运行权限为root

gid = rsync        设置rsync运行权限为root

use chroot = no     修改为no,增加对目录文件软连接的备份

read only = no              设置rsync服务端文件为读写权限

list = no                         不显示rsync服务端资源列表

max connections = 20            最大连接数

log file = /var/log/rsyncd.log            日志文件位置

pidfile = /var/run/rsyncd.pid      pid文件的存放位置

lock file = /var/run/rsync.lock     支持max connections参数的锁文件

secrets file = /etc/rsync.passwd    虚拟用户的密码文件,后面会创建这个文件

transfer logging = yes                     使 rsync 服务器将传输操作记录到传输日志文件

timeout = 600                                设置超时时间

ignore nonreadable = yes              指定 rysnc 服务器完全忽略那些用户没有访问权限的文件

dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 

指定那些在传输之前不进行压缩处理的文件

 

  

[backup]       自定义模块名称

        path = /backup      需要同步的备份目录

        ignore errors        表示出现错误忽略错误  

        comment = backup   给模块指定一个描述        

auth users = user1     执行数据同步的用户名,可以设置多个,用英文逗号隔开

 

4、创建虚拟用户认证文件并设置权限

[root@backup ~]# echo "user1:123456" >/etc/rsync.passwd

[root@backup ~]# cat /etc/rsync.passwd

user1:123456     注:user1为虚拟用户,123456为这个虚拟用户的密码

[root@backup ~]# chmod 600 /etc/rsync.passwd

 

5、启动rsync服务并查看端口是否开启

[root@backup ~]# rsync --daemon

[root@backup ~]# netstat -antp|grep 873

tcp        0      0 0.0.0.0:873     0.0.0.0:*       LISTEN      12313/rsync        

tcp6       0      0 :::873          :::*           LISTEN      12313/rsync 

 

6、在数据服务器安装Rsync客户端并创建密码文件

[root@server ~]# yum -y install rsync

[root@server ~]# rpm -q rsync

rsync-3.0.9-18.el7.x86_64

[root@server ~]# echo "123456"> /etc/passwd.txt  注:passwd.txt密码文件里只写密码即可

[root@server ~]# chmod 600 /etc/passwd.txt

 

7、在数据服务器上测试能否推送备份成功

[root@server ~]# rsync -avz /server/www/ user1@192.168.115.130::backup --password-file=/etc/passwd.txt

sending incremental file list

./

1.txt

a.txt

sent 147 bytes  received 49 bytes  392.00 bytes/sec

total size is 26  speedup is 0.13

 

上面推送成功之后,到备份服务器查看是否备份成功

[root@backup ~]# ls /backup/

1.txt  a.txt

通过测试发现我们已经可以从数据服务器同步文件到备份服务器了。

 

五、安装inotify-tools配合rsync实现数据实时备份

1、查看服务器内核是否支持inotify

[root@server ~]# ll /proc/sys/fs/inotify   出现下面的内容,说明内核支持inotify

-rw-r--r-- 1 root root  0 3   3 17:48 max_queued_events

-rw-r--r-- 1 root root  0 3   3 17:48 max_user_instances

-rw-r--r-- 1 root root  0 3   3 17:48 max_user_watches

备注:Linux下支持inotify的内核最小为2.6.13,可以输入命令:uname -a查看内核

 

2、下载源码包并安装inotify-tools

[root@server ~]# yum -y install make gcc gcc-c++

[root@server ~]# wget --no-check-certificate https://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

[root@server ~]# tar -xf inotify-tools-3.14.tar.gz

[root@server ~]# cd inotify-tools-3.14

[root@server inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify

[root@server inotify-tools-3.14]# make && make install

 

3inotifyinotifywait命令常用参数及可监控的事件

inotifywait命令参数

-m        始终保持事件监听状态。

-r         使用递归形式监视目录。

-q         减少冗余信息,只打印监控事件的信息。

-e         指定要监视的事件列表。

--timefmt   是指定时间的输出格式。

--format    打印使用指定的输出类似格式字符串。

--excludei   排除文件或目录时,不区分大小写。


 

可监听的事件

事件

描述

access

读取文件或目录内容

modify

修改文件或目录内容

attrib

文件或目录的属性改变

close_write

修改真实文件内容

move

移动文件或目录移动到监视目录

moved_to

文件或目录移动到

moved_from

文件或目录从移动

create

在监视目录下创建文件或目录

open

文件或目录被打开

close

关闭,对文件进行关闭操作。

delete

删除监视目录下的文件或目录

unmount

卸载文件系统

 

 

4、修改inotify默认参数(inotify默认内核参数值太小)

1)查看系统默认参数

[root@server ~]# sysctl -a | grep max_queued_events

fs.inotify.max_queued_events = 16384    监控队列大小,如果值太小,会出错

[root@server ~]# sysctl -a | grep max_user_watches

fs.inotify.max_user_watches = 8192       同时同一用户可以监控的目录数量

[root@server ~]# sysctl -a | grep max_user_instances

fs.inotify.max_user_instances = 128      每个用户创建inotify实例最大值

 

2)修改后的参数(参数可根据需要适当调大)

使用下面的这种方法修改的参数是生效的

[root@server ~]# echo 65535 > /proc/sys/fs/inotify/max_user_instances

[root@server ~]# echo 999999 > /proc/sys/fs/inotify/max_queued_events

[root@server ~]# echo 9 > /proc/sys/fs/inotify/max_user_watches

 

注意:按照网上说法在/etc/sysctl.conf里添加或在/usr/lib/sysctl.d/50-default.conf文件添加下面的参数都是无效的。本人亲测!

[root@server ~]# vim /etc/sysctl.conf

max_queued_events = 999999     

max_user_instances = 65535    

max_user_watches = 999999   

 

[root@server ~]# vim /usr/lib/sysctl.d/50-default.conf

max_queued_events = 999999     

max_user_instances = 65535      

max_user_watches = 999999   

5、编写监控脚本并加载到后台执行

[root@server ~]# cat inotify.sh

#!/bin/bash

host=192.168.115.130     #备份服务器IP

src=/server/www         #数据服务器需要备份的目录

dst=backup                            #备份服务器的备份数据目录

user=user1                                 #rsync --daemon定义的验证用户名

rsync_passfile=/etc/passwd.txt    # rsync验证的密码文件

inotify_home=/usr/local/inotify    #inotify安装路径

 

#判断上面这些目录和文件是否全部存在

if [ ! -e "$src" ] || [ ! -e "${rsync_passfile}" ] || [ ! -e "${inotify_home}/bin/inotifywait" ] || [ ! -e "/usr/bin/rsync" ];

   then

     echo "Please check whether there is a directory or file"

   exit 9

fi

 

#这里必须要先cd到源目录,inotify再监听,./ 才能rsync同步后目录结构一致

cd ${src}

${inotify_home}/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file

#把监控到有发生更改的"文件路径列表"循环

do

# inotify输出切割 把事件类型部分赋值给INO_EVENT

        INO_EVENT=$(echo $file | awk '{print $1}')

# inotify输出切割 把文件路径部分赋值给INO_FILE

        INO_FILE=$(echo $file | awk '{print $2}')

        echo "-------------------------------$(date)------------------------------------"

        echo $file

#这里判断是否有文件的创建、修改、移动等操作

        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]

        then

                echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'

#如果有上面的条件则同步文件到目标服务器

                rsync -avzcR --password-file=${rsync_passfile} $(dirname ${INO_FILE}) ${user}@${host}::${dst}

        fi

#这里判断是否有文件的删除、移动的操作

        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]

        then

                echo 'DELETE or MOVED_FROM'

#如果有上面的条件则同步文件到目标服务器

                rsync -avzR --delete --password-file=${rsync_passfile} $(dirname ${INO_FILE}) ${user}@${host}::${dst}

        fi

#这里判断文件的属性是否发生改变

        if [[ $INO_EVENT =~ 'ATTRIB' ]]

        then

                echo 'ATTRIB'

                if [ ! -d "$INO_FILE" ]

                then

#如果有上面的条件则同步文件到目标服务器

                        rsync -avzcR --password-file=${rsync_passfile} $(dirname ${INO_FILE}) ${user}@${host}::${dst}

                fi

        fi

done

 

给脚本授予执行权限并在后台运行脚本监控

[root@server ~]# chmod +x inotify.sh

[root@server ~]# nohup ./inotify.sh &

[root@server ~]# ps -aux|grep inotify

root     14741  0.0  0.1 113132  1420 pts/2    S    11:23   0:00 /bin/bash ./inotify.sh

root     14742  0.0  0.0   6480   644 pts/2    S    11:23   0:00 /usr/local/inotify/bin/inotifywait -mrq --format %Xe %w%f -e modify,create,delete,attrib,close_write,move ./

root     14743  0.0  0.0 113132   384 pts/2    S    11:23   0:00 /bin/bash ./inotify.sh

6、设置定时任务,防止意外导致无法同步

因为inotify只在启动时会监控目录,他没有启动期间的文件发生更改,他是不知道的,所以这里每2个小时做1次全量同步,防止各种意外遗漏,保证目录一致。

[root@localhost ~]# crontab -e

* */2 * * * rsync -avz --password-file=/etc/passwd.txt /server/www/ user1@192.168.115.130::backup

 

7 实时同步测试

1)在数据服务器端创建文件,看是否能够同步备份

在数据服务器创建文件并查看

[root@server ~]# touch /server/www/{1..5}.txt

[root@server ~]# ls /server/www/

1.txt  2.txt  3.txt  4.txt  5.txt

 

在备份服务器查看是否同步备份

[root@backup ~]# ls /backup/

1.txt  2.txt  3.txt  4.txt  5.txt

2)在数据服务器端删除文件,看是否能够同步删除

在数据服务器删除文件并查看

[root@server ~]# rm -f /server/www/1.txt /server/www/2.txt

[root@server ~]# ls /server/www/

3.txt  4.txt  5.txt

 

在备份服务器查看是否同步删除

[root@backup ~]# ls /backup/

3.txt  4.txt  5.txt

 

3)在数据服务器端修改文件内容,看是否能够同步内容

在数据服务器修改文件内容并查看

[root@server ~]# echo -e "33333333333\n444444444444">/server/www/3.txt

[root@server ~]# cat /server/www/3.txt

33333333333

444444444444

 

在备份服务器查看文件内容是否同步

[root@backup ~]# cat /backup/3.txt

33333333333

444444444444

 

4)修改文件权限看能否同步

在数据服务器修改文件权限并查看

[root@server ~]# ls -l /server/www/

-rw-r--r-- 1 root root 25 3   5 11:37 3.txt

-rw-r--r-- 1 root root  0 3   5 11:28 4.txt

-rw-r--r-- 1 root root  0 3   5 11:28 5.txt

[root@server ~]# chmod 755 /server/www/*

[root@server ~]# ls -l /server/www/

-rwxr-xr-x 1 root root 25 3   5 11:37 3.txt

-rwxr-xr-x 1 root root  0 3   5 11:28 4.txt

-rwxr-xr-x 1 root root  0 3   5 11:28 5.txt

在备份服务器查看文件权限是否同步

[root@backup ~]# ls -l /backup/

-rwxr-xr-x 1 rsync rsync 25 3   5 11:37 3.txt

-rwxr-xr-x 1 rsync rsync  0 3   5 11:28 4.txt

-rwxr-xr-x 1 rsync rsync  0 3   5 11:28 5.txt

 

以上所有的测试做完之后,发现都可以同步,说明我们的rsync+inotify实现数据实时备份已经配置完成了