【linux运维】rsync+inotify与sersync+rsync实时数据同步笔记

Rsync(remote sync)远程同步工具,通过rsync可以实现对远程服务器数据的增量备份通过,但rsync自身也有缺陷,同步数据时,rsync采用核心算法对远程服务器的目标文件进行对比,只进行差异同步。我们可以想象一下,如果服务器的文件数量达到了百万甚至千万量级,那么文件对比是非常耗时的,而且发生变化的往往是其中很少的一部分,这是非常低效的方式。inotify的出现,可以缓解rsync不足之处,取长补短。

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

注释:下面的inotify配置时建立在rsync服务基础上的配置过程
1.1 查看服务器内核是否支持inotify功能

[root@root backup]# uname -r
2.6.32-431.el6.x86_64
[root@root backup]# ls -l /proc/sys/fs/inotify/
总用量 0
-rw-r--r-- 1 root root 0 12月 22 09:03 max_queued_events
-rw-r--r-- 1 root root 0 12月 22 09:03 max_user_instances
-rw-r--r-- 1 root root 0 12月 22 09:03 max_user_watches

1.2.下载inotify-tools安装包,地址:https://sourceforge.net/projects/inotify-tools/postdownload
1.3.上传服务器进行解压安装。

[root@root soft]# tar -zxvf inotify-tools-3.13.tar.gz 
[root@root soft]# cd inotify-tools-3.13
[root@root inotify-tools-3.13]# ./configure --prefix=/usr/local/inotify-tools-3.13
[root@root inotify-tools-3.13]# make && make install
[root@root inotify-tools-3.13]# ln -s /usr/local/inotify-tools-3.13/ /usr/local/inotify
[root@root inotify-tools-3.13]# ls -l /usr/local/inotify/
总用量 16
drwxr-xr-x. 2 root root 4096 12月 22 12:36 bin # inotify监控执行命令(二进制)
drwxr-xr-x. 3 root root 4096 12月 22 12:36 include #inotify程序所需用的头文件
drwxr-xr-x. 2 root root 4096 12月 22 12:36 lib #动态链接的库文件
drwxr-xr-x. 4 root root 4096 12月 22 12:36 share #帮助文档
[root@root inotify-tools-3.13]# ls -l /usr/local/inotify/bin/  #两个监控命令
总用量 80
-rwxr-xr-x. 1 root root 38598 12月 22 12:36 inotifywait
-rwxr-xr-x. 1 root root 40369 12月 22 12:36 inotifywatch

1.4.两个监控命令可以通过--help查看详解

[root@root inotify-tools-3.13]# /usr/local/inotify/bin/inotifywait --help
        -m|--monitor    Keep listening for events forever.  Without
                        this option, inotifywait will exit after one
                        event is received.
        -r|--recursive  Watch directories recursively.
        -q|--quiet      Print less (only print events).
        --exclude <pattern>
                        Exclude all events on files matching the
                        extended regular expression <pattern>.   
       --format <fmt>  Print using a specified printf-like format
                        string; read the man page for more details.
       --timefmt <fmt> strftime-compatible format string for use with
                        %T in --format string.   
       -e|--event <event1> [ -e|--event <event2> ... ]
                Listen for specific event(s).  If omitted, all events are 
                listened for.
Exit status:
        0  -  An event you asked to watch for was received.
        1  -  An event you did not ask to watch for was received
              (usually delete_self or unmount), or some error occurred.
        2  -  The --timeout option was given and no events occurred
              in the specified interval of time.                                   
Events:
        access          file or directory contents were read
        modify          file or directory contents were written
        attrib          file or directory attributes changed
        close_write     file or directory closed, after being opened in
                        writeable mode
        close_nowrite   file or directory closed, after being opened in
                        read-only mode
        close           file or directory closed, regardless of read/write mode
        open            file or directory opened
        moved_to        file or directory moved to watched directory
        moved_from      file or directory moved from watched directory
        move            file or directory moved to or from watched directory
        create          file or directory created within watched directory
        delete          file or directory deleted within watched directory
        delete_self     file or directory was deleted
        unmount         file system containing file or directory unmounted

1.5.看小型拓扑图
【linux运维】rsync+inotify与sersync+rsync实时数据同步笔记

1.6. 编写事件监控脚本

#!/bin/bash
#para
###设置变量
host01=192.168.120.120
src=/backup
dst=backup
user=rsync_backup
rsync_passfile=/etc/rsync.password
inotify_home=/usr/local/inotify/
#rsync -aruz $user@$host01::$dst --password-file=${rsync_passfile}

#judge  检验判断上述变量
if [ ! -e  "$src" ] 
|| [ ! -e "${rsync_passfile}" ] 
|| [ ! -e "${inotify_home}/bin/inotifywait" ] 
|| [ ! -e "/usr/bin/rsync" ];
then
    echo "Check File and Folder"
    exit 9
fi
#用inotifywait命令检测数据同步目录变化,出现变化后,使用rsync进行实时同步
${inotify_home}/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write,delete,create,attrib $src 
| while read file
do
    cd $src && rsync -aruz -R --delete ./ --timeout=100 $user@$host01::$dst --password-file=${rsync_passfile} >/dev/null 2>&1
done
exit 0


1.7 注:配置inotify时系统的默认参数值
查看系统默认参数值:

[root@rsync ~]# sysctl -a | grep max_queued_events 
fs.inotify.max_queued_events = 16384
[root@rsync ~]# sysctl -a | grep max_user_instances
fs.inotify.max_user_instances = 128
[root@rsync ~]# sysctl -a | grep max_user_watches 
fs.inotify.max_user_watches = 8192
修改参数:
sysctl -w fs.inotify.max_queued_events="99999999"
sysctl -w fs.inotify.max_user_watches="99999999"
sysctl -w fs.inotify.max_user_instances="65535"
[root@rsync ~]# vi /etc/sysctl.conf #添加以下代码
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535

参数说明:
max_queued_events:
inotify队列最大长度,如果值太小,会出现" Event Queue Overflow "错误,导致监控文件不准确
max_user_watches:
要同步的文件包含多少目录,可以用:find /home/wwwroot/ -type d | wc -l 统计,必须保证max_user_watches值大于统计结果(这里/home/wwwroot/为同步文件目录)
max_user_instances:
每个用户创建inotify实例最大值

第二部分:sersync+rsync实时数据同步
2.1.sersync介绍
1.sersync是基于inotify开发的,类似于inotify-tools的工具
2.sersync可以记录下被监听目录中发生变化的(包括增加、删除、修改)具体某一个文件或者某一个目录的名字,然后使用rsync同步的时候,只同步发生变化的文件或者目录
2.2 sersync具有以下几个优点
1.sersync是使用c++编写,而且对linux系统文件系统产生的临时文件和重复的文件操作进行过滤,所以在结合rsync同步的时候,节省了运行时耗和网络资源。因此更快。
2.sersync配置起来很简单,其中bin目录下已经有基本上静态编译的2进制文件,配合bin目录下的xml配置文件直接使用即可。
3.使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态。
4.有出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则按设定时长对同步失败的文件重新同步。
5.自带crontab功能,只需在xml配置文件中开启,即可按要求隔一段时间整体同步一次。无需再额外配置crontab功能。
6.能够实现socket与http插件扩展。
2.3 安装sersync(前提条件先安装好rsync)
2.3.1 wget 下载sersync安装包

https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sersync/sersync2.5_32bit_binary_stable_final.tar.gz #32位
https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sersync/sersync2.5.4_64bit_binary_stable_final.tar.gz #64位
2.3.2 解压缩到 /usr/local/sersync/ 下,编辑配置文件confxml.xml(记得先备份,在编辑)
sersync的配置文件confxml.xml详解。自己学习修改功能,
1.可修改26行本地目录、服务器模块、IP;
2.认证部分【rsync密码认证】
3.定义同步失败后重新同步的时间和错误日志
4.具体需根据生产环境需求修改

<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>    #hostip与port是针对插件的保留字段,对于同步没有任何作用,保留默认即可。
    <debug start="false"/>  #开启debug模式,会在sersync正在运行的控制台,打印inotify事件与rsync同步命令。
    <fileSystem xfs="false"/>   #对于xfs文件系统的用户,需要将这个选项开启,才能是sersync正常工作。

    <filter start="false">
        <exclude expression="(.*).svn"></exclude>
        <exclude expression="(.*).gz"></exclude>
        <exclude expression="^info/*"></exclude>
        <exclude expression="^static/*"></exclude>
    </filter>   #对于sersync监控的文件,会默认过滤系统的临时文件(以"."开头,以"~"结尾),除了这些文件外,可以自定义其他需要过滤的文件。

    <inotify>
        <delete start="true"/>
        <createFolder start="true"/>
        <createFile start="false"/>
        <closeWrite start="true"/>
        <moveFrom start="true"/>
        <moveTo start="true"/>
        <attrib start="false"/>
        <modify start="false"/>
    </inotify>  #inotify监控参数,对于大多数应用,可以把createFile设置为false来提高性能,减少rsync通讯,因为拷贝文件到监控目录会产生create事件与close_write事件,所以如果关闭create事件,只监控文件拷贝时结束的事件close_write,同样可以实现文件完整同步。    #注意:要将createFolder保持为true,如果将createFloder设置为false,则不会对产生的目录进行监控,该目录下的子文件与子目录也不会被监控,所以除非特殊需要,请开启。默认情况下对创建文件(目录)事件与删除文件(目录)事件都进行监控,如果项目中不需要删除远程目标服务器的文件(目录),则可以将delete参数设置为false,则不会删除事件监控。

    <sersync>
        <localpath watch="/backup"> 
            <remote ip="192.168.120.120" name="backup"/>
            <!--<remote ip="192.168.8.39" name="tongbu"/>--> #注:可添加rsync.conf中多个模块的名字
            <!--<remote ip="192.168.8.40" name="tongbu"/>-->
        </localpath>
         #/backup目录为sersync主服务器本地待同步的目录,ip为从服务器的ip地址,name="backup",backup为rsync.conf中模块的名字。
        <rsync>
            <commonParams params="-artuz"/> #rsync的同步参数
            <auth start="true" users="rsync" passwordfile="/etc/rsync.password"/>#可填写虚拟用户rsync,本地密码文件路径
            <userDefinedPort start="false" port="874"/><!-- port=874 -->
            <timeout start="false" time="100"/><!-- timeout=100 -->
            <ssh start="false"/>    #如果开启就是使用 rsync -e ssh的方式进行传输
        </rsync>
        <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once--> #失败日志脚本配置 #如果文件同步失败,会重新传送,再次失败就会写入rsync_fail_log.sh,然后每隔一段时间(timetoexecute进行设置)执行该脚本再次重新传送,然后清空该脚本。
        <crontab start="false" schedule="600"><!--600mins-->    #每隔一段时间整体同步。如果文件量比较大,crontab的时间间隔要设的大一些,否则可能增加通讯开销。如果开启了filter文件过滤功能,那么crontab整体同步也需要设置过滤,否则虽然实时同步的时候文件被过滤了,但crontab整体同步的时候,如果不单独设置crontabfilter,还会将需要过滤的文件同步到远程服务器,crontab的过滤正则与fileter过滤的不同。
            <crontabfilter start="false">   #如果同时开启了filter与crontab,则要开启crontab的crontabfilter。
                <exclude expression="*.php"></exclude>
                <exclude expression="info/*"></exclude>
            </crontabfilter>
        </crontab>
        <plugin start="false" name="command"/>  #设置为true,将文件同步到远程服务器后会条用name参数指定的插件。如果需要使用插件则需要在启动实例的时候加上-m参数
    </sersync>

    <plugin name="command">
        <param prefix="/bin/sh" suffix="" ignoreError="true"/>  <!--prefix /opt/tongbu/mmm.sh suffix-->
        <filter start="false">
            <include expression="(.*).php"/>
            <include expression="(.*).sh"/>
        </filter>
    </plugin>   #当同步文件完成后,会调用command插件,如同步文件是test.php,则test.php文件再改动后,调用rsync同步到远程服务器后,调用command插件,执行/bin/sh test.php suffix >/dev/null 2>&1
    #如果suffix设置了,则会放在inotify事件test.php之后,如果ignoError为true,则会添加>/dev/null 2>&1,当然还可以设置command的filter,当filter为true,include可以只对正则匹配到的文件调用command。
    <plugin name="socket">
        <localpath watch="/opt/tongbu">
            <deshost ip="192.168.138.20" port="8009"/>
        </localpath>
    </plugin>   #向指定ip与端口发送inotify所产生的文件路径信息。
        <plugin name="refreshCDN">
        <localpath watch="/data0/htdocs/cms.xoyo.com/site/">
            <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
            <sendurl base="http://pic.xoyo.com/cms"/>
            <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
        </localpath>
    </plugin>   
    #在同步的过程中将文件发送到目的服务器后刷新cdn接口。改模块是根据chainaCDN的协议进行设计,当有文件产生的时候,就向cdn接口发送需要刷新的路径位置。
    #localpath是需要监控的目录,cdninfo标签制定了cdn接口的域名,端口号,以及用户名与密码。
    #sendurl标签是需要刷新的url的前缀。regexurl标签中的,regex属性为true时,使用match属性的正则语句匹配inotify返回的路径信息,并将正则匹配到的部分作为url一部分。
    举例:
    如果产生文件事件为:/data0/htdocs/cms.xoyo.com/site/jx3.xoyo.com/image/a/123.txt
    经过上面的match正则匹配后,最后刷新的路径是:http://pic.xoyo.com/cms/jx3/a/123.txt
    如果regex属性为false,最后刷新的路径是:http://pic.xoyo.com/cms/jx3.xoyo.com/images/a/123.txt
</head>#自定义超端口

2.3.3 配置完后,开启sersync守护进程同步数据
启动方法

/usr/local/sersync/bin/sersync2 -r -d -o /usr/local/sersync/conf/confxml.xml

-d daemon方式启动
-n 启用线程数量
-o 指定配置文件
-r 递归同步目录数据
整个sersync设置完毕!最后可以写脚本并添加chkconfig或者直接加命令到rc.local完成自启动。

转载于:https://blog.51cto.com/000011211684/2367231