CentOS下利用rsync inotify实现数据实时同步 - 图1
之前有简单介绍Rsync同步工具CentOS6下远程数据同步工具Rsync的使用

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

inotify-tools

inotify是一种强大的、细粒度的、异步的文件系统事件监控机制,Linux内核从2.6.13开始引入,允许监控程序打开一个独立文件描述符,并针对事件集监控一个或者多个文件,例如打开、关闭、移动/重命名、删除、创建或者改变属性
CentOS6已经默认支持,cd /proc/sys/fs/inotify目录后使用ll命令查看,是否有以下三条信息输出,如果没有表示不支持
CentOS下利用rsync inotify实现数据实时同步 - 图2

  • /proc/sys/fs/inotify/max_queued_evnets表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
  • /proc/sys/fs/inotify/max_user_instances表示每一个real user ID可创建的inotify instatnces的数量上限。
  • /proc/sys/fs/inotify/max_user_watches表示每个inotify instatnces可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小

附:当文件及文件夹的数量特别大时,需要修改inotify默认参数(inotify默认内核参数值太小)
查看系统默认参数值
sysctl -a | grep max_queued_events
结果是:fs.inotify.max_queued_events = 16384
sysctl -a | grep max_user_watches
结果是:fs.inotify.max_user_watches = 8192
sysctl -a | grep max_user_instances
结果是:fs.inotify.max_user_instances = 128
修改参数:
sysctl -w fs.inotify.max_queued_events=”99999999”
sysctl -w fs.inotify.max_user_watches=”99999999”
sysctl -w fs.inotify.max_user_instances=”65535”
vi /etc/sysctl.conf #添加以下代码
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535
:wq! #保存退出


inotify-tools:inotify-tools是为linux下inotify文件监控工具提供的一套C的开发接口库函数,同时还提供了一系列的命令行工具,这些工具可以用来监控文件系统的事件。 inotify-tools是用c编写的,除了要求内核支持inotify外,不依赖于其他。inotify-tools提供两种工具,一是inotifywait,它是用来监控文件或目录的变化,二是inotifywatch,它是用来统计文件系统访问的次数

可以使用yum install inotify-tools进行安装
CentOS下利用rsync inotify实现数据实时同步 - 图3inotifywait使用示例
监控/data/目录文件的变化
/usr/bin/inotifywait -mrq —timefmt ‘%Y/%m/%d-%H:%M:%S’ —format ‘%T %e %w %f’ -e modify,delete,create,move,attrib /data/
持续监听/data目录及其子目录的文件变化,监听事件包括文件被修改、删除、创建、移动、属性更改,显示到屏幕。执行完上面的命令后,在/data/下创建或修改文件都会有信息输出
image.png


下面介绍rsync组合inotify-tools完成实时同步

创建排除在外不同步的文件列表

排除不需要同步的文件或目录有两种做法,第一种是inotify监控整个目录,在rsync中加入排除选项,简单;第二种是inotify排除部分不监控的目录,同时rsync中也要加入排除选项,可以减少不必要的网络带宽和CPU消耗。我们选择第二种
inotifywait排除
notifywait排除监控目录有—exclude 和—fromfile 两种格式,并且可以同时使用,但主要前者可以用正则,而后者只能是具体的目录或文件
使用fromfile格式只能用绝对路径,不能使用诸如*正则表达式去匹配,@表示排除

rsync排除

使用inotifywait排除监控目录的情况下,必须同时使用rsync排除对应的目录,否则只要有触发同步操作,必然会导致不该同步的目录也会同步。与inotifywait类似,rsync的同步也有—exclude和—exclude-from两种写法


客户端同步到远程服务器的脚本rsync_toAliyun.sh

image.png

先前已经在阿里云服务器上搭建好Rsync服务端,参考之前的文档
CentOS6下远程数据同步工具Rsync的使用

[root@PXEKickstart ~]# vi rsync_toAliyun.sh
#rsync auto sync script with inotify
#variables
current_date=$(date +%Y%m%d
%H%M%S)
source_path=/data/
log_file=/var/log/rsync_client.log
#rsync
rsync_server=101.132.116.99
rsync_user=rsyncbackup
rsync_pwd=/etc/rsync_client.pwd
rsync_module=backup
INOTIFY_EXCLUDE=’(./.zip|./.gz|./.log)’
RSYNC_EXCLUDE=’/etc/rsyncd.d/rsync_exclude.lst’
#rsync client pwd check
if [ ! -e ${rsync_pwd} ];then
echo -e “rsync client passwod file ${rsync_pwd} does not exist!”
exit 0
fi
#inotify_function
inotify_fun(){
/usr/bin/inotifywait -mrq —timefmt ‘%Y/%m/%d-%H:%M:%S’ —format ‘%T %e %w %f’ —exclude ${INOTIFY_EXCLUDE} -e modify,delete,create,move,attrib ${source_path} | while read file
do
/usr/bin/rsync -auvrtzopgP —exclude-from=${RSYNC_EXCLUDE} —progress —password-file=${rsync_pwd} ${source_path} ${rsync_user}@${rsync_server}::${rsync_module}
done
}
#inotify&log
inotify_fun >> ${log_file} 2>&1 &
image.png
1)创建/etc/rsyncd.d/rsync_exclude.lst
排除备份源目录下子目录tmp文件夹,以及排除tar.gz,zip,log后缀名文件
2)rsync客户端同步用户的密码文件/etc/rsync_client.pwd
image.png
注意:客户端的密码文件与服务端不一样,不需要加用户名,这个坑排查了很久,根据rsync同步日志报错关键字在网上搜索到相关答案
https://bbs.csdn.net/topics/392070584
CentOS下利用rsync inotify实现数据实时同步 - 图8
在客户端执行脚本./rsync_toAliyun.sh后,源目录创建文件,可以看到服务端正在进行实时同步
CentOS下利用rsync inotify实现数据实时同步 - 图9