rsync+inotify实时同步

一、概况

1.1、组合起源

Rsync(remote sync),通过rsync可以实现对远程服务器数据的增量备份同步,但rsync本身也有瓶颈,同步数据时采用核心算法对远程服务器目标文件进行比对,只进行差异同步。如果服务器文件数量达到百万甚至千万级别,比对将是非常耗时的。而发生变化的往往是其中很少一部分。inotify的出现,可以缓解rsync不足之处,取长补短。同时也是实现实时同步的一种方式。

1.2、inotify简介

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

1.3、结构

rsync_inotify_Top

当inotify服务器上文件变化时,就会触发将变化的文件传给rsync服务端进行同步。

二、安装

2.1、准备

使用两台Linux机器,一台(A)开启rsync daemon服务进程,在另一台(B)上确保可以执行同步数据过去。

A机器:rsync服务端配置可以参考之前的博文

RS_A

B机器测试同步:

echo apache > rsyncd.password
chmod 400 rsyncd.password
rsync -avPh /tmp/ [email protected]::test --password-file=rsyncd.password

RS_B

已经同步成功,在A上查看:

RS_CK_A

2.2、安装inotify-tools

B机器(客户端)上配置:

检查系统是否支持:

inotify_ck_support

下载、安装(inotify-tools 3.14 is the latest version, released on the 7th of March 2010.):

wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar zxf inotify-tools-3.14.tar.gz -C /usr/local/src/
cd /usr/local/src/inotify-tools-3.14/
CFLAGS="-fPIC -O3" ./configure --prefix=/usr/local/inotify
make -j `cat /proc/cpuinfo | grep processor | wc -l` && make install
echo 'export PATH=/usr/local/inotify/bin/:$PATH' > /etc/profile.d/inotify.sh
source /etc/profile.d/inotify.sh

三、Rsync+Inotify联合应用

3.1、测试监听事件

mkdir /backup
inotifywait -mrq --timefmt "%Y/%m/%d %H:%M" --format "%T %Xe %w%f" -e create,delete,attrib,modify /backup/

这里监控了创建、修改、删除和属性变更的操作。

重新开个窗口在所监控的目录下面进行相关操作:

inotify_test_1

可以看到操作事件已经被监听到:

inotify_test_2

3.2、close_write与modify

会有这样一种情况,向inotify监控目录持续与入一个大的文件时,inotify会持续不断的输出该文件的modify信息,对于后面的制作脚本来说,就会不断地触发rsync同步操作,占用大量系统资源。针对这种情况,只需将modify监控事项改为close_write即可。如:

inotifywait -mrq --timefmt "%Y/%m/%d %H:%M" --format "%T %Xe %w%f" -e create,delete,attrib,modify,close_write /backup/

colse_modify1

colse_modify2

可以很明显的看到,当对文件持续写入时,colse_write只会在写入完成后生成一次事件。

3.3、制作简单脚本

上面的操作我们已可以提取到变化的目前和文件,接下来就是如何使用了。

vim inotify.sh
#!/bin/bash
#Author:Chris

Red='\033[31m\033[1m'
Green='\033[32m\033[1m'
Null='\033[0m'
#----config----
Bindir=/usr/local/inotify/bin
Src=/backup
User=apache
Host=172.16.220.225
Dst=test
Pass=/etc/rsyncd.password
#----config----
if [ -x $Bindir/inotifywait ];then
        inotifywait=$Bindir/inotifywait
else
        echo -e ${Red}command inotifywait cant not fond in ${Bindir}${Null}
        exit 0
fi
if [ ! -f ${Pass} ];then
        echo -e ${Red}${Pass} does not exist${Null}
        exit 0
fi
cd ${Src}
${inotifywait} -mrq --format "%Xe %w %f" -e create,delete, close_write,attrib ${Src} \
| while read event dir file
do
        if [[ $event =~ 'CREATE' ]] || [[ $event =~ 'CLOSE' ]];then
                ffile=${dir}${file}
                fpath=$(echo ${ffile} | sed 's_'$Src'/__')
                rsync -arzR ${fpath} ${User}@${Host}::${Dst} --password-file=${Pass} > /dev/null 2>&1
        fi
        if [[ $event =~ 'DELETE' ]];then
                dpath=.$(echo ${dir} | sed 's_'$Src'__')
                rsync -arzR --delete ${dpath} ${User}@${Host}::${Dst} --password-file=${Pass} > /dev/null 2>&1
        fi
        if [[ $event =~ 'ATTRIB' ]];then
                ffile=${dir}${file}
                if [ ! -d ${ffile} ];then
                        rsync -arzR ${fpath} ${User}@${Host}::${Dst} --password-file=${Pass} > /dev/null 2>&1
                fi
        fi
done
chmod +x inotify.sh

3.4、测试

A机器(Rsync服务端)上,将准备过程中同步过来的文件删掉,目录留空:

Pre_RI_TEST

B机器执行上步创建的脚本,为了直观的看到过程,加了-x选项:

bash -x inotify.sh

创建文件:

查看过程:

结果:

执行删除:

RI_rm_1

RI_rm_fin

四、优化脚本

以上脚本可满足一般使用。但其中存在问题,当处理文件较多,执行较频繁时,将会出现灾难性的问题:如,执行touch {1..1000}其会产生CREATE、ATTRIB事件,这样同一个文件会重复执行2次,1000个文件会循环运行2000次执行rsync;又如,在一个目录下执行了rm -rf *,这样一个目录下有多少文件就要执行多少次,相当“不智能”,而且会耗费大量资源,于是需要优化。

脚本这里就不全发上来了,有兴趣的可以留言索要,下面是部分截图:

        脚本看上去虽然比较复杂,但完全可以避免上述情况的发生:inotifywait监控目标目录,当有监视的事件发生时,同时最多生成thread=4个线程进行执行;当事件为create、modify、attrib时,会检测、判断目标文件是否存在,并以Interval=1秒为间隔,若在1秒之内,上次执行传输过同一文件,则此次不执行;当事件为delete时,会将删除文件的上层目录进行同步,会判断目录是否存在,同样会判断在1秒之内是否有执行过此目录的同步。

五、系统参数调整

在/proc/sys/fs/inotify目录下有三个文件,对inotify机制有一定的限制

max_user_watches #设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)

max_user_instances #设置每个用户可以运行的inotifywait或inotifywatch命令的进程数

max_queued_events #设置inotify实例事件(event)队列可容纳的事件数量

默认这三个参数数值为:

inotify_sys_proc

主要修改监视文件数量和队列数值:

echo 65536000 > /proc/sys/fs/inotify/max_user_watches
echo 327680 > /proc/sys/fs/inotify/max_queued_events

《rsync+inotify实时同步》有1条评论

回复 ljw 取消回复

error: Content is protected !!