CentOS6.8使用rsync sersync实现数据实时同步

有运维或运维开发方面的需求,可以联系博主QQ 452336092或Email:admin#centos.bz(收费)

文章目录
[隐藏]

Sersync简介

Sersync利用inotifyrsync对服务器进行实时同步,其中inotify用于监控文件系统事件,rsync是目前广泛使用的同步算法,其优点是只对文件不同的部分进行操作,所以其优势大大超过使用挂接文件系统的方式进行镜像同步。由金山的周洋开发完成,是目前使用较多的文件同步工具之一。该工具和其他的工具相比有如下优点:

  • sersync是使用c++编写,由于只同步发生更改的文件,因此比其他同步工具更节约时间、带宽;

  • 安装方便、配置简单;

  • 使用多线程进行同步,能够保证多个服务器实时保持同步状态;

  • 自带出错处理机制,通过失败队列对出错的文件重新出错,如果仍旧失败,则每10个小时对同步失败的文件重新同步;

  • 自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次;
    自带socket与http协议扩展,你可以方便的进行二次开发;

rsync+sersync与rsync+Inotify-tools区别

Inotify-tools只能记录下被监听的目录发生了变化(包括增加、删除、修改),并没有把具体是哪个文件或者哪个目录发生了变化记录下来;

rsync在同步的时候,并不知道具体是哪个文件或者哪个目录发生了变化,每次都是对整个目录进行同步,当数据量很大时,整个目录同步非常耗时(rsync要对整个目录遍历查找对比文件),因此,效率很低。

sersync是基于Inotify开发的,类似于Inotify-tools的工具;

sersync可以记录下被监听目录中发生变化的(包括增加、删除、修改)具体某一个文件或某一个目录的名字;

rsync在同步的时候,只同步发生变化的这个文件或者这个目录(每次发生变化的数据相对整个同步目录数据来说是很小的,rsync在遍历查找比对文件时,速度很快),因此,效率很高。

所以,当同步的目录数据量不大时,建议使用Rsync+Inotify-tools;当数据量很大(几百G甚至1T以上)、文件很多时,建议使用Rsync+sersync。

地址:http://code.google.com/p/sersync/,要翻墙才能下载

http://download.csdn.net/detail/hellopengyl/9918625

安装、配置

和Inotify-tools一样,只需要在数据源端安装

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

[root@localhost src]# ll /proc/sys/fs/inotify    #查看服务器内核是否支持inotify,出现下面的内容,说明服务器内核支持inotify
total 0
-rw-r--r-- 1 root root 0 Jul 27 10:32 max_queued_events
-rw-r--r-- 1 root root 0 Jul 27 10:32 max_user_instances
-rw-r--r-- 1 root root 0 Jul 27 10:32 max_user_watches
[root@localhost src]# uname -r        #Linux下支持inotify的内核最小为2.6.13
2.6.32-642.el6.x86_64
[root@localhost src]# sysctl -a|egrep -i "max_queued_events|max_user_watches|max_user_instances"    #修改inotify默认参数(inotify默认内核参数值太小)
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 8192
fs.inotify.max_queued_events = 16384
fs.epoll.max_user_watches = 201420
[root@localhost src]# vim /etc/sysctl.conf
fs.inotify.max_user_instances = 65535
fs.inotify.max_user_watches = 99999999
fs.inotify.max_queued_events = 99999999    
[root@localhost src]# cat /proc/sys/fs/inotify/{max_user_instances,max_user_watches,max_queued_events}
65535
99999999
99999999
[root@localhost src]#
  • max_queued_events inotify队列最大长度,如果值太小,会出现”** Event Queue Overflow **”错误,导致监控文件不准确

  • max_user_watches 要同步的文件包含多少目录,可以用:find /home/www.osyunwei.com -type d | wc -l统计,必须保证max_user_watches值大于统计结果(这里/home/www.osyunwei.com为同步文件目录)

  • max_user_instances 每个用户创建inotify实例最大值

2、安装、配置sersync

[root@localhost src]# tar zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@localhost src]# mv GNU-Linux-x86 /app/sersync
[root@localhost src]# cd /app/sersync/
[root@localhost sersync]# ls
confxml.xml  sersync2
[root@localhost sersync]# cp confxml.xml{,.default}
[root@localhost sersync]# vim confxml.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>    #针对插件的保留字段,保留默认即可。
    <debug start="true"/>    #在sersync正在运行的控制台,打印inotify,rsync同步命令
    <fileSystem xfs="false"/>    #对于xfs文件系统用户,需要将这个选项开启才正常工作
    <filter start="false">    #过滤系统的临时文件,被过滤的文件不会被监控提高,默认过滤系统的临时文件(以“.”开头,以“~”结尾)
    <exclude expression="(.*)\.svn"></exclude>
    <exclude expression="(.*)\.gz"></exclude>
    <exclude expression="^info/*"></exclude>
    <exclude expression="^static/*"></exclude>
    </filter>
    <inotify>    #inotify监控文件模块
    <delete start="true"/>    #如果本地文件删除,不需要删除远程段的文件可以设置成false
    <createFolder start="true"/> #如果将createFolder设为false,则不会对产生的目录进行监控,该目录下的子文件与子目录也不会被监控;
    <createFile start="false"/>  #把createFile(监控文件事件选项)设置为false来提高性能,减少rsync通讯;因为拷贝文件到监控目录会产生create事件与close_write事件,所以如果关闭create事件,只监控文件拷贝结束时的时间close_write,同样可以实现文件完整同步;
    <closeWrite start="true"/>
    <moveFrom start="true"/>
    <moveTo start="true"/>
    <attrib start="false"/>
    <modify start="false"/>
    </inotify>

    <sersync>    #进行数据同步的模块
    <localpath watch="/app/rsync_client">    #定义本地要同步的目录
        <remote ip="10.15.43.100" name="app_rsync_server"/>#远程接受同步的IP和rsync模块名
        <!--<remote ip="192.168.8.39" name="tongbu"/>-->
        <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    </localpath>
    <rsync>
        <commonParams params="-artuz"/>    #自定义rsync参数,默认是-artuz
        <auth start="true" users="rsync" passwordfile="/etc/rsyncd.secret"/>    #开启用户认证,定义用户名密码
        <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-->  #对于失败的传输,会进行重新传送,再次同步失败后日志记录到/tmp/rsync_fail_log.sh,并且每60分钟对失败的log进行重新同步
    <crontab start="true" schedule="600"><!--600mins-->    #每隔600s会做一次完全同步
        <crontabfilter start="false">    #如果开启了filter文件过滤功能,那么crontab整体同步也需要设置过滤,否则虽然实时同步的时候文件被过滤了,但crontab整体同步的时候 如果不单独设置crontabfilter,还会将需过滤的文件同步到远程,
        <exclude expression="*.php"></exclude> #crontab的过滤正则与filter过滤的不同,果同时开启了filter与crontab,则要开启crontab的crontabfilter,并按示例设置使其与filter的过滤一一对应。
        <exclude expression="info/*"></exclude>
        </crontabfilter>
    </crontab>
        <plugin start="false" name="command"/>    #当设置为true的时候,将文件同步到远程服务器后会调用name参数指定的插件。
    </sersync>

    <plugin name="command">    #name指定的插件
    #当文件同步完成后,会调用command插件,例如同步文件是file.txt,file.txt文件在改动之后,调用rsync同步到远程服务器后,调用command插件,执行/bin/sh file.txt suffix >/dev/null 2>&1
    #如果suffix 设置了,则会放在inotify事件file.txt之后,如果ignoreError为true,则会添加>/dev/null 2>&1
    <param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix-->
    <filter start="false">
        <include expression="(.*)\.php"/>    #当filter为ture,include可以只对正则匹配到的文件,调用command。
        <include expression="(.*)\.sh"/>
    </filter>
    </plugin>
        #http插件,可以向指定域名的主机post,inotify监控的事件。
        #socket插件,开启该模块,则向指定ip与端口发送inotify所产生的文件路径信息
    <plugin name="socket">    
    <localpath watch="/opt/tongbu">
        <deshost ip="192.168.138.20" port="8009"/>
    </localpath>
    </plugin>
    #在同步过程中将文件发送到目的服务器后刷新cdn接口。如果不想使用,则设置<plugin start="false" name="refreshCDN"/>
    #该模块根据chinaCDN的协议,进行设计,当有文件产生的时候,就向cdn接口发送需要刷新的路径位置
    <plugin name="refreshCDN">    
    <localpath watch="/data0/htdocs/cms.xoyo.com/site/">  #需要监控的目录
            #cdnifo标签制定了cdn接口的域名,端口号,以及用户名与密码。
        <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
        #sendurl标签是需要刷新的url的前缀
        <sendurl base="
        #regexurl标签中的,regex属性为true时候,使用match属性的正则语句匹配inotify返回的路径信息,并将正则匹配到的部分作为url一部分,
        <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
            #如果产生文件事件为:/data0/htdoc/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;
    </localpath>
    </plugin>
</head>
[root@localhost sersync]# /app/sersync/sersync2 -d -r -n 8 -o /app/sersync/confxml.xml
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
parse the command param
option: -d    run as a daemon
option: -r    rsync all the local files to the remote servers before the sersync work
option: -n    thread num is:  8
option: -o    config xml name:  /app/sersync/confxml.xml
parse xml config file
host ip : localhost  host port: 8008
Open debug, you will see debug infomation 
daemon start,sersync run behind the console 
Start the crontab    Every 600 minutes rsync all the files to the remote servers entirely
use rsync password-file :
user is    rsync
passwordfile is   /etc/rsyncd.secret
config xml parse success
please set /etc/rsyncd.conf max connections=0 Manually
sersync working thread 10  = 1(primary thread) + 1(fail retry thread) + 8(daemon sub threads) 
Max threads numbers is: 18 = 10(Thread pool nums) + 8(Sub threads)
please according your cpu ,use -n param to adjust the cpu rate
------------------------------------------
rsync the directory recursivly to the remote servers once
working please wait...
execute command: cd /app/rsync_client && rsync -artuz -R --delete ./ rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
crontab command:cd /app/rsync_client && rsync -artuz -R --delete ./ rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
run the sersync: 
watch path is: /app/rsync_client
add watch: /app/rsync_client return wd is: 1
add watch: /app/rsync_client/test return wd is: 2
[root@localhost sersync]#
  • -d 后台启动

  • -r 同步前将已存在的文件全部同步过去,如果设置了过滤器,即在xml文件中,filter为true,则暂时不能使用-r参数进行整体同步;

  • -n 开启的线程总数默认10

  • -o 指定配置文件,指定 -o 参数可以指定多个不同的配置文件,从而实现sersync多进程多实例的数据同步

  • -m 不进行同步,只运行插件 ./sersync -m pluginName 例如:./sersync -m command,则在监控到事件后,不对远程目标服务器进行同步,而是直接运行command插件

[root@localhost sersync]# cat monitor_sersync.sh #监控Sersync运行状态的脚本,如果服务停止了就重启服务
#!/bin/bash
server_file="/app/sersync/sersync2"
conf_file="/app/sersync/confxml.xml"
options="-d -r -n 8 -o"
proc_num=$(ps -ef|grep -i sersync2|grep -v "grep"|wc -l)
if [ $proc_num -lt 1 ];then
    cd $(dirname $server_file)
    nohup $server_file $options $conf_file &
else
   exit 0;
fi
[root@localhost sersync]# chmod +x monitor_sersync.sh 
[root@localhost sersync]# crontab -l
*/5 * * * *  /app/sersync/monitor_sersync.sh
[root@localhost sersync]# /etc/init.d/crond restart
[root@localhost sersync]# vim /etc/rc.d/rc.local    #设置开机自动运行脚本
/app/sersync/sersync2 -d -r -n 8 -o /app/sersync/confxml.xml
[root@localhost sersync]#

测试

在客户端监控的目录/app/rsync_client创建文件,然后查看服务器端app_rsync_server模块对应的目录是否同步更新

[root@localhost rsync_client]# touch file{1..9}
inotify wd:1   name:file1  mask:256
inotify wd:1   name:file1  mask:8
inotify wd:1   name:file2  mask:256
inotify wd:1   name:file2  mask:8
inotify wd:1   name:file3  mask:256
inotify wd:1   name:file3  mask:8
inotify wd:1   name:file4  mask:256
inotify wd:1   name:file4  mask:8
inotify wd:1   name:file5  mask:256
[root@localhost rsync_client]# cd /app/rsync_client && rsync -artuz -R "./file2" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
inotify wd:1   name:file5  mask:8
inotify wd:1   name:file6  mask:256
inotify wd:1   name:file6  mask:8
inotify wd:1   name:file7  mask:256
inotify wd:1   name:file7  mask:8
inotify wd:1   name:file8  mask:256
inotify wd:1   name:file8  mask:8
inotify wd:1   name:file9  mask:256
inotify wd:1   name:file9  mask:8
cd /app/rsync_client && rsync -artuz -R "./file1" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
cd /app/rsync_client && rsync -artuz -R "./file3" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
cd /app/rsync_client && rsync -artuz -R "./file4" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
cd /app/rsync_client && rsync -artuz -R "./file5" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
cd /app/rsync_client && rsync -artuz -R "./file6" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
cd /app/rsync_client && rsync -artuz -R "./file7" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
cd /app/rsync_client && rsync -artuz -R "./file8" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
cd /app/rsync_client && rsync -artuz -R "./file9" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret
[root@localhost rsync_client]# touch file1
inotify wd:1   name:file1  mask:8
[root@localhost rsync_client]# cd /app/rsync_client && rsync -artuz -R "./file1" rsync@10.15.43.100::app_rsync_server --password-file=/etc/rsyncd.secret

[root@localhost sersync]#

压测

写入10K个文件批量同步测试结果:

[root@localhost rsync_client]# for n in {1..10000};do dd if=/dev/zero of=/app/rsync_client/"$n".txt bs=1M count=5;done

查看同步速度,当10K个文件同步完后,在/app/rsync_server里发现才同步了600多个文件

多实例情况

配置多个confxml.xml文件(比如:www、bbs、blog….等等),根据不同的需求同步对应的实例文件

[root@localhost rsync_client]# /app/sersync/sersync2 -d -r -n 8 -o /app/sersync/www_confxml.xml
[root@localhost rsync_client]# /app/sersync/sersync2 -d -r -n 8 -o /app/sersync/bbs_confxml.xml
[root@localhost rsync_client]# /app/sersync/sersync2 -d -r -n 8 -o /app/sersync/blog_confxml.xml

原文出处:51cto -> http://ityunwei2017.blog.51cto.com/7662323/1953004

打赏

如果此文对你有所帮助,请随意打赏鼓励作者^_^