sersync自动同步

sersync项目介绍

      Sersync项目利用inotify与rsync技术实现对服务器数据实时同步的解决方案其中inotify用于监控sersync所在服务器上文件系统的时间变化,rsync是目前广泛使用的本地及异地数据同步工具,其优点是只对变化的目录数据操作,甚至是一个文件不同部门进行同步,所以其优势大大超过使用挂接文件系统或scp等方式进行镜像同步。

目前使用的比较多的同步程序版本是inotify-tools,另外一个是google开源项目Openduckbill(依赖于inotify-tools),这两个都是基于脚本语言编写的,其设计思路同样是采用inotify与rsync命令。

相比以上两个项目,sersync项目的优点是:

     ①.使用C++编写,对linux系统文件产生的临时文件和重复的文件操作会进行过滤,在结合rsync同步的时候回减少运行时消耗本地及网络资源,因此速度更快。

     ②.相比较上面两个项目,sersync配置起来很简单:在htto://code.google.com/p/sersync处下载源码(分为32位与64位版本),其中bin目录下是一已经编译好的二进制文件,配合bin目录下的xml文件直接使用即可。

     ③.使用多线程进行 同步(即可以并发同多个不同文件),尤其在同步较大文件时,能够保证多个服务器实时保持同步状态。

     ④.sersync自带出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则每数个小时对同步失败的文件再重新同步。

     ⑤.Sersync自带crontab功能,只需在xml配置文件中开启,即可按预先的配置,隔一段时间整体同步一次。

     ⑥.Sersync自带socket与http的协议扩展,可以满足有特殊需求的公司二次开发。

sersync基本架构

     ①.线程组线程是等待线程队列的守护进程,当队列中有数据的时候,线程组守护进程逐个唤醒,当队列中inotify事件较多的时候就会全部唤醒一起工作。这样设计的目的是能够同时处理多个inotify时间,提升服务器的并发同步能力(核数*2+2)

           之所以称止为线程,是因为每个线程在工作的时候,会根据服务上写入文件的数量建立子线程,子线程可以保证所有的文件与各个服务器同时同步,当要同步的文件较大的时候,这样设计可以保证各个远程服务器可以同时获得要同步的文件。

     ②.服务线程的作用有三个:

          a)首先要处理同步失败的文件,将这些文件再次同步,对于再次失败的文件会生成rsync_fail_log.sh脚本,记录失败的事件。

          b)同时每隔10个小时执行脚本一次,同时清空脚本

          c)第三个作用是crontab功能,可以每隔一定事件,将所有路径整体同步一次

    ③.过滤队列的建立是为了过滤短时间内产生的重复的inotify信息,例如在删除文件夹的时候,inotify就会同时产生删除文件夹里的文件和删除文件夹的事件,通过过滤队列,当删除文件夹事件产生的时候,会将之前加入队列的删除文件的事件全部过滤掉,这样只产          生一条删除文件夹事件,从而减轻了同步的负担。同时对于修改文件操作的时候,会产生临时文件的重复操作。

sersync同步 

    sersync依赖rsync进行数据同步。如下图:在同步主服务器(test3)上开启sersync,sersync负责监控配置路径中的文件系统事件变化,然后调用rsync命令把更新的文件同步到目标服务器(test1-test2),因此,需要在主服务器配置sersync,在同步目标服务器配置rsync server(注意是rsync服务)。

    如图,用户会实时的往左边的同步主服务器(test3)上写入或更新文件数据,此时需要在左边的同步服务器(test3)上配置sersync服务,在左边的同步目标服务器test1和test3服务器上配置rsync守护进程,这样在主服务器test3上产生的写入或更新的文件,就会被sersync服务实时同步到多个目标服务器(test1、test2等)。在主服务器(test3)上有rsync命令即可,在目标服务器(test1、test2)上只需进行简单的配置,并开启rsync守护进程即可。

    提示:学习rsync的守护进程服务后就会发现,实际上sersync就是监控本地的数据写入或更新事件,然后,调用rsync客户端的命令,将写入或更新事件对应的文件通过rsync推送到目标服务(例如test1、test2),就这么简单

部署环境

角色

服务器配置

操作系统版本

IP

机器名

sersync服务

VM

CentOS6.4|2.6.32-358.el6.i686

192.168.3.102/24

test3

rsync服务

VM

CentOS6.4|2.6.32-358.el6.i686

192.168.3.100/24

test1

rsync服务

VM

CentOS6.4|2.6.32-358.el6.i686

192.168.3.101/24

test2

 

♧部署rsync服务(在多台目标服务器test1,test2..上相同配置)

安装

[root@test1 ~]# yum install -y rsync	#安装rsync             [rsync version 3.0.6]
[root@test1 ~]# cat >/etc/rsyncd.conf<<EOF
transfer logging = yes
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
port = 873
address = 192.168.3.100			#监听的网卡IP,test2上改为192.168.3.101
uid = root        #rsync是通过这个设定的用户来访问下面配置的path路径
gid = root		    #所以这个用户要对下面配置的path路径要有相应的权限
use chroot = no
read only = false		#设置为false,客户端可以上传文件,设置为true就不能推送只能拉取
max connections = 2000
Timeout = 600
ignore errors
auth users = rsyncd_bk
secrets file = /etc/rsyncd.passwd
hosts allow = 192.168.3.0/255.255.255.0
hosts deny = *
list = false
########################################				#设置了三个模块
[www]
comment = www by heboan
path = /data0/www/
########################################
[bbs]
comment = bbs by heboan
path = /data1/bbs/
########################################
[blog]
comment = blog by heboan
path = /data2/blog/
EOF 

    提示:test1,test2的机器192.168.3.100,192.168.3.101同时部署上诉服务,上面的rsync服务的配置文件,表明允许sersync主服务器(192.168.3.102)访问,rsync同步模块名为[www][bbs][blog],将同步过来的文件分别放入对应path指定的目录/data0/www/,/data1/bbs/,/data2/blog/下。如果有多台目标服务器,则每一台都需要进行类似的rsync服务配置,上面的uid,gid要换成你服务器的相应的同步用户,注意,rsync服务账户(本文用了root)要有对同步目录的写入更新权限。

创建相关待同步目录

# mkdir -p /data0/www /data1/bbs /data2/blog

配置相关权限认证

# echo "rsyncd_bk:pass123" >/etc/rsyncd.passwd
# chmod 600 /etc/rsyncd.passwd 
# ll /etc/rsyncd.passwd 
-rw-------. 1 root root 18 Apr 20 21:31 /etc/rsyncd.passwd

开启rsync守护进程

# rsync --daemon
# ps -ef |grep rsync|grep -v grep
root      1710     1  0 21:32 ?        00:00:00 rsync --daemon
# netstat -lnt |grep 873
tcp        0      0 192.168.3.100:873           0.0.0.0:*                   LISTEN

设置开机启动

# which rsync
/usr/bin/rsync
# echo "#rsync service daemon by heboan 20150420" >>/etc/rc.local 
# echo "/usr/bin/rsync --daemon" >>/etc/rc.local 

重启命令

# pkill rsync
# ps -ef |grep rsync|grep -v grep
# rsync --daemon
# ps -ef |grep rsync|grep -v grep
root      1746     1  0 21:43 ?        00:00:00 rsync --daemon

到此test1已经配置完成,test2的配置和test1一样,这里就不再写出步骤,和上面一样即可

 

♧在test3上配置rsync客户端

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

在test3上配置rsync客户端相关权限认证
[root@test3 ~]# echo "pass123" >/etc/rsyncd.passwd
[root@test3 ~]# chmod 600 /etc/rsyncd.passwd 
[root@test3 ~]# ll /etc/rsyncd.passwd 
-rw-------. 1 root root 8 Apr 20 22:21 /etc/rsyncd.passwd

test3上手工测试rsync同步情况

特别强调:此步非常关键,如果这里测试不成功,后面的sersync配好了也不会同步数据

①分别创建待同步的数据

[root@test3 ~]# mkdir -p /data0/www /data1/bbs /data2/blog
[root@test3 ~]# touch /data0/www/www.log /data1/bbs/bbs.log /data2/blog/blog.log
[root@test3 ~]# ls /data0/www/ /data1/bbs/ /data2/blog/
/data0/www/:
www.log

/data1/bbs/:
bbs.log

/data2/blog/:
blog.log

②执行同步命令

rsync -avzP /data0/www/ rsyncd_bk@192.168.3.100::www/ --password-file=/etc/rsyncd.passwd
rsync -avzP /data0/www/ rsyncd_bk@192.168.3.101::www/ --password-file=/etc/rsyncd.passwd 

rsync -avzP /data1/bbs/ rsyncd_bk@192.168.3.100::bbs/ --password-file=/etc/rsyncd.passwd
rsync -avzP /data1/bbs/ rsyncd_bk@192.168.3.101::bbs/ --password-file=/etc/rsyncd.passwd 

rsync -avzP /data2/blog/ rsyncd_bk@192.168.3.100::blog/ --password-file=/etc/rsyncd.passwd
rsync -avzP /data2/blog/ rsyncd_bk@192.168.3.101::blog/ --password-file=/etc/rsyncd.passwd

③同步完成之后,test1,test2上的对应目录应该有*.log的文件

[root@test1 ~]# ls /data0/www/ /data1/bbs/ /data2/blog/
/data0/www/:			/data1/bbs/:			/data2/blog/:
www.log			       bbs.log			        blog.log

[root@test2 ~]# ls /data0/www/ /data1/bbs/ /data2/blog/
/data0/www/:			/data1/bbs/:			/data2/blog/:
www.log				bbs.log				blog.log

♧在test3上开始部署sersync服务

 

下载sersync

    在google code下载sersync的可执行文件版本,里面有配置文件与可执行文件,这里用sersync2.5进行说明,新版配置形式类似。

    下载地址:http://sersync.googlecode.com,根据自己的系统版本选择32位或64位的下载

安装sersync

[root@test3 ~]# tar zxf sersync2.5_32bit_binary_stable_final.tar.gz -C /usr/local/
[root@test3 ~]# cd /usr/local/;ls
bin  etc  games  GNU-Linux-x86  include  lib  libexec  sbin  share  src
[root@test3 local]# mv GNU-Linux-x86 sersync
[root@test3 local]# ls sersync/
confxml.xml  sersync2

规范sersync目录结构

[root@test3 local]# cd sersync/
[root@test3 sersync]# mkdir conf bin logs
[root@test3 sersync]# mv confxml.xml conf
[root@test3 sersync]# mv sersync2 bin/sersync
[root@test3 sersync]# tree
.
├── bin
│   └── sersync
├── conf
│   └── confxml.xml
└── logs

配置sersync

    因为需要同步三个模块[www]、[bbs]、[blog],这里我们需要创建三个与之对应的配置文件,如果只是同步一个模块,我们只需要一个配置文件confxm.xml就可以了(注意:修改配置文件前记得备份)

[root@test3 sersync]# cd conf/
[root@test3 conf]# cp confxml.xml www_confxml.xml
[root@test3 conf]# cp confxml.xml bbs_confxml.xml
[root@test3 conf]# cp confxml.xml blog_confxml.xml
[root@test3 conf]# mkdir bk		#创建一个目录,用来放置备份配置文件的
[root@test3 conf]# mv confxml.xml  bk/		#把备份的配置文件放入备份目录
[root@test3 conf]# ls
bbs_confxml.xml  bk  blog_confxml.xml  www_confxml.xml

修改配置文件www_confxml.xml(bbs_confxml.xml、blog_confxml.xml同理修改)

①修改24-28行的部分,原内容为:
 
 24		<localpath watch="/opt/tongbu">
 25		    <remote ip="127.0.0.1" name="tongbu1"/>
 26		    <!--<remote ip="192.168.8.39" name="tongbu"/>-->
 27		    <!--<remote ip="192.168.8.40" name="tongbu"/>-->
 28		</localpath>
 
修改后的内容为:
        <localpath watch="/data0/www">
             <remote ip="192.168.3.100" name="www"/>
             <remote ip="192.168.3.101" name="www"/>
        </localpath>
提示:此步watch="/data0/www"就是定义服务端待同步的目录,和目标服务器的模块name="www"
-----------------------------------------------------------------------------------
bbs_confxml.xml修改为:
       <localpath watch="/data1/bbs">
             <remote ip="192.168.3.100" name="bbs"/>
             <remote ip="192.168.3.101" name="bbs"/>
        </localpath>

blog_confxml.xml修改为:
       <localpath watch="/data2/blog">
             <remote ip="192.168.3.100" name="blog"/>
             <remote ip="192.168.3.101" name="blog"/>
        </localpath>
②修改29-35(修改前的行号),认证部分,原内容为:
 29		<rsync>
 30		    <commonParams params="-artuz"/>	#同步的参数
 31		    <auth start="false" users="root" passwordfile="/etc/rsync.pas"/>
 32		    <userDefinedPort start="false" port="874"/><!-- port=874 -->
 33		    <timeout start="false" time="100"/><!-- timeout=100 -->
 34		    <ssh start="false"/>
 35		</rsync>

修改后的内容为:(其他两个配置文件修改为一样即可) <rsync> <commonParams params="-artuz"/> <auth start="true" users="rsyncd_bk" passwordfile="/etc/rsyncd.passwd"/> <userDefinedPort start="false" port="874"/><!-- port=874 --> <timeout start="true" time="100"/><!-- timeout=100 --> <ssh start="false"/> </rsync>

 细心一点我们就能明白,其实上面的几个配置就是在拼接rsync -artuz --timeout=100 /data0/www/ rsyncd_bk@192.168.3.100:www/ --password-file=/etc/rsyncd.passwd这个同步的命令而已

③修改36行(修改前的行号),原内容为
36	     <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->

修改后的内容为:
     <failLog path="/usr/local/sersync/logs/www_rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->

提示:当同步失败后,日志记录到/usr/local/sersync/logs/www_rsync_fail_log.sh,并且每60分钟对失败的log进行重新同步
-----------------------------------------------------------------------------------
bbs_confxml.xml修改为:
     <failLog path="/usr/local/sersync/logs/bbs_rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
	 
blog_confxml.xml修改为:
     <failLog path="/usr/local/sersync/logs/blog_rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->

配置sersync环境变量

[root@test3 ~]# echo 'export PATH=$PATH:/usr/local/sersync/bin'>>/etc/profile
[root@test3 ~]# tail -1 /etc/profile
export PATH=$PATH:/usr/local/sersync/bin
[root@test3 ~]# source /etc/profile
[root@test3 ~]# which sersync
/usr/local/sersync/bin/sersync

启动命令

sersync -r -d -o /usr/local/sersync/conf/www_confxml.xml
sersync -r -d -o /usr/local/sersync/conf/bbs_confxml.xml
sersync -r -d -o /usr/local/sersync/conf/blog_confxml.xml

参数说明:
-r  :用来第一次同步初始化目录,是服务器两边的内容保持一致
-d  :在后台运行
-o  :用来指定配置文件

♧sersync同步测试(省略)

附:

Sersync配置文件说明(XML配置文件:confxml.xml)

提示:xml配置文件注释不是“#”,而是<!--中间是注释内容-->

1	<?xml version="1.0" encoding="ISO-8859-1"?>
2	<head version="2.5">
3	    <host hostip="localhost" port="8008"></host>
hostip与port是针对插件的保留字段,对于同步功能没有任何作用,保留默认即可
4	    <debug start="false"/>
设置为true,开启debug模式,会在sersync正在运行的控制台打印inotify事件与rsync同步命令
5	    <fileSystem xfs="false"/>
对于xfs文件系统的用户,需要将这个选项开启,才能使sersync正常工作
对于sersync监控的文件,会默认过滤系统的临时文件(以“.”开头,以“~”结尾),除了这些文件外,可以自定义需要过滤的文件
6	    <filter start="false">
7		<exclude expression="(.*)\.svn"></exclude>
8		<exclude expression="(.*)\.gz"></exclude>
9		<exclude expression="^info/*"></exclude>
10		<exclude expression="^static/*"></exclude>
11	    </filter>
将start设置为true后开启过滤功能,在exclude标签中,填写正则表达式,默认给出两个例子分别是过滤以“.gz”结尾的文件与过滤监控目录下的info路径(监控路径/info/*),可以根据需要添加,但开启的时候,自己测试一下,正则表达式如果出现错误,控制台会有提示。相比较使用rsync的exclude功能,被过滤的路径,不会加入监控,大大减少了rsync同步的通讯量
对于inotify监控参数可以进行设置,根据项目的特点优化rsync
12	    <inotify>
13		<delete start="true"/>
14		<createFolder start="true"/>
15		<createFile start="false"/>
16		<closeWrite start="true"/>
17		<moveFrom start="true"/>
18		<moveTo start="true"/>
19		<attrib start="false"/>
20		<modify start="false"/>
21	    </inotify>
对于大多数应用,可以尝试把createFile(监控文件事件选项)设置为false来提高性能,减少rsync通讯。因为拷贝文件到监控目录会产生create事件与close_write事件,所以如果关闭create事件,只监控文件拷贝结束时的事件close_write,同样可以实现文件完整同步。
注意:需要将createFolder保持为true,如果将createFolder设为false,则不会对产生的目录进行监控,该目录下的子文件与子目录也不会被监控。所以除非特殊需要,请开启。默认情况下对创建文件(目录)事件与删除文件(目录)事件都进行监控,如果项目中不需要删除远程目标服务器的文件(目录),则可以将delete参数设置为false,则不对删除事件进行监控。
22	
23	    <sersync>
文件监控与远程同步设置
24		<localpath watch="/opt/tongbu">
25		    <remote ip="127.0.0.1" name="tongbu1"/>
26		    <!--<remote ip="192.168.8.39" name="tongbu"/>-->
27		    <!--<remote ip="192.168.8.40" name="tongbu"/>-->
28		</localpath>
/opt/tongbu目录为sersync主服务器本地待同步的目录,ip=”192.168.8.39”为从服务器的IP地址,如果有多个从服务器,依次列出来即可。name=”tongbu”,这里的tongbu为rsyncd.conf中的模块名字,即中括号中的名称
Rsync设置
29		<rsync>
30		    <commonParams params="-artuz"/>
31		    <auth start="false" users="root" passwordfile="/etc/rsync.pas"/>
32		    <userDefinedPort start="false" port="874"/><!-- port=874 -->
33		    <timeout start="false" time="100"/><!-- timeout=100 -->
34		    <ssh start="false"/>
35		</rsync>
在commonParams项,我们可以自定义rsync的同步参数,默认是-artuz,auth start=”false”设置为true的时候,使用rsync的认证模式传送,需要配置user与passwordfile(--password-file=)来使用。userDenfinedPort当远程同步目标服务器的rsync端口不是默认端口的时候使.timeout这是rsync的timout事件。<ssh start=”false”/>如果开启,ssh使用rsync -e ssh的方式传输。
失败日志脚本配置
36		<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
如果文件同步传输失败,会重新传送,再次失败就会写入rsync_fail_log.sh,然后每个一段时间(timeToExecute进行设置)执行该脚本再次重新传送,然后清空该脚本。可以通过path来设置日子路径。
Crontab定期整体同步功能
37		<crontab start="false" schedule="600"><!--600mins-->
38		    <crontabfilter start="false">
39			<exclude expression="*.php"></exclude>
40			<exclude expression="info/*"></exclude>
41		    </crontabfilter>
42		</crontab>
Crontab可以对监控路径与远程目标主机每隔一段时间进行一次整体同步,可能由于一些原因再次重传失败,这个时候如果开启了crontab功能,还可以进一步保证各个服务器文件一致,如果文件量比较大,crontab的时间间隔要设大一些,否则可能增加通讯开销。Schedule这个参数设置crontab的时间间隔,默认是600分钟。如果开启了filter文件过滤功能,那么crontab整体同步也需要设置过滤,否则虽然实时同步的文件被过滤了,但是crontab整体同步的时候,如果不单独设置crontabfilter,还会将需过滤的文件同步到远程从服务器,,crontab的过滤正则与filter过滤的不同,也给出了两个实例分别对应与过滤文件与目录。总之如果同时开启了filter与crontab,则要开启crontab的crontabfilter,并按示例设置使其与filter的过滤一一对应。
插件设置
43		<plugin start="false" name="command"/>
当start=”false”处设置为true的时候,将文件同步到远程服务器后会调用插件。通过name参数指定需要执行的插件。目前支持的有command refreshCDN socket http四种插件。其中,http插件目前由于兼容性原因已经去除,以后会重新加入
44	    </sersync>
45	
Command插件
46	    <plugin name="command">
47		<param prefix="/bin/sh" suffix="" ignoreError="true"/>	<!--prefix /opt/tongbu/mmm.sh suffix-->
48		<filter start="false">
49		    <include expression="(.*)\.php"/>
50		    <include expression="(.*)\.sh"/>
51		</filter>
52	    </plugin>
当文件同步完成后,会调用command插件,如同步文件时test.php,则test.php文件再改动之后,调用rsync同步到远程服务器后,调用command插件,执行 :/bin/sh test.php  suffix>dev/null 2>&1
如果suffix设置了,则会放在inotify事件test.php之后,如果ignoreError为true,则会添加>/dev/null 2>&1,当然还可以设置command的filter,当filter为true时,include可以只对正则匹配到的文件调用command.
53	
Socke插件,开启该模块,则向指定的ip与端口发送inotify所产生的文件路径信息
54	    <plugin name="socket">
55		<localpath watch="/opt/tongbu">
56		    <deshost ip="192.168.138.20" port="8009"/>
57		</localpath>
58	    </plugin>
59	    <plugin name="refreshCDN">
60		<localpath watch="/data0/htdocs/cms.xoyo.com/site/">
61		    <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
62		    <sendurl base="http://pic.xoyo.com/cms"/>
63		    <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
64		</localpath>
“refreshCDN”,就在同步过程中将文件发送到目的服务器后刷新cdn接口。如果不想使用,则将start属性设为false即可。
如果需要使用其他插件,则查看其他plugin标签,将插件名称改为xml中其他插件名称即可。该模块根据chinaCDN的协议进行设计,当有文件产生的时候,就向cdn接口发送需要刷新的路径位置。
其中localpath watch=”/data0/hotdocs/cms.xoyo.com/site”是需要监控的目录。cdninfo标签制定了cdn接口的域名,端口号,以及用户名与密码。
sendurl标签是需要刷新的url的前缀。regexurl标签中的,regex属性为true的时候,使用match属性的正则语句匹配inotify返回的路径信息,并将正则匹配到的部分作为url一部分。
举例:
如果产生的文件事件为:/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
65	    </plugin>
66	</head>

###############################################################################################
只调用command插件
./sersync -d -m command
只调用refreshCDN插件
./sersync -d -m refreshCDN
只调用socket插件
./sersync -d -m socket
原文地址:https://www.cnblogs.com/sellsa/p/5345092.html