目录:
sersync项目简介:
Sersync服务器同步程序 项目简介与设计框架
sersync下载地址:http://code.google.com/p/sersync/downloads/list
sersync基本功能的安装配置详见:
sersync2 完全安装配置说明(一) —-基本功能使用
sersync功能的定制和高级配置详见:
sersync2 完全安装配置说明(二) —-可选功能与xml高级配置
sersync插件配置详见:
sersync2 完全安装配置说明(三) —-插件基本配置和使用
sersync编译:
sersync需要二次开发的用户请参考
项目简介:
本项目利用inotify与rsync对服务器进行实时同步,其中inotify用于监控文件系统事件,rsync是目前广泛使用的同步算法,其优点是只对文件不同的部分进行操作,所以其优势大大超过使用挂接文件系统的方式进行镜像同步。
目前使用的比较多的同步程序版本是inotify-tools,另外一个是google开源项目Openduckbill(依赖于inotify-tools),这两个都是基于脚本语言编写的,其设计思路同样是采用inotify与rsync命令。 相比较上面两个项目,本项目优点是:
1.sersync是使用c++编写,而且对linux系统文件系统产生的临时文件和重复的文件操作进行过滤(我稍后会提到),所以在结合rsync同步的时候,节省了运行时耗和网络资源。因此更快。
2.相比较上面两个项目,sersync配置起来很简单:在http://code.google.com/p/sersync/downloads/list 处下载源码(分为32版本,与64位版本),其中bin目录下已经有我编译好的2进制文件,配合bin目录下的xml文件直接使用即可。
3.另外本项目相比较其他脚本开源项目,使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态。
4.本项目自带出错处理机制,通过失败队列对出错的文件重新出错,如果仍旧失败,则每10个小时对同步失败的文件重新同步。
5.本项目自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次。
6.本项目自带socket与http协议扩展,满足您二次开发的需要。
基本架构:
设计简析:
如上图所示,线程组线程是等待线程队列的守护线程,当队列中有数据的时候,线程组守护线程逐个唤醒,当队列中inotify事件交多的时候就会被全部唤醒一起工作。这样设计的目的是能够同时处理多个inotify事件,重发利用服务器的并发能力(核数*2+2)。
之所以称之为线程组线程,是因为每个线程在工作的时候,会根据服务器的数量建立子线程,子线程可以保证所有的文件与各个服务器同时同步,当要同步的文件较大的时候,这样设计可以保证各个远程服务器可以同时获得要同步的文件。
服务线程的作用有三个,首先是处理同步失败的文件,将这些文件再次同步,对于再次同步失败的文件会生成rsync_fail_log.sh脚本,记录失败的事件。同时每隔10个小时执行脚本一次,同时清空脚本。服务线程的第三个作用是crontab功能,可以每隔一定时间,将所有路径整体同步一次。
过滤队列的建立是为了过滤短时间内产生的重复的inotify信息,例如在删除文件夹得时候,inotify就会同时产生删除文件夹里的文件与删除文件夹得事件,通过过滤队列当删除文件夹事件产生的时候,会将之前加入队列的删除文件的事件全部过滤掉,这样只产生一条事件减轻了同步的负担。同时对于修改文件的操作的时候,会产生临时文件与重复操作。
举例:
当我们在vi的一个test文件,进行wq操作的时候会产生如下事件:
即使把”.”开头与”~”结尾的世界过滤了,对于test文件仍旧有3次操作,分别是删除,创建与保存,通过过滤队列,就只剩下一个事件,一定程度上也提高了效率。
过滤队列第二个作用,即当你在本机删除目录的时候,假设你删除一个有5个文件的目录,inotify会产生6个事件,分别是5个文件删除事件,和一个删除目录事件,如果使用过滤队列,正常情况下会只产生一个删除目录的事件,大大减少了rsync通信次数。(当然,这不是绝对的。如果这6个事件分多次读到进入队列,那么可能还没来得及过滤,就已经被同步线程从队列中取走同步了。但一定程度上可以减少删除文件夹得同步通信次数)。
过滤队列的第三个作用,可以过滤监控目录下的文件夹,如果不想同步目录下的一些文件夹,或者一些后缀的文件。对于不需监控的子文件夹,在inotify启动时候remove掉监控,对于不需监控子文件,产生的文件事件就会从在入同步队列前过滤掉。如果使用rsync用–exclude, 这样虽然也可以过滤,但还是与rsync守护进程进行了一次交互。
目的:
要把同步服务器中的目录/opt/tongbu1实时同步到三个同步目标主服务器中的/opt/tongbu1目录中。以做到文件的实时备份!
如上图所示,需要在同步主服务器上配置sersync,在同步目标服务器配置rsync,并在目标服务器开启rsync守候进程,这样在主服务器产生的文 件,就会被sersync实时同步到多个目标服务器。在CentOS系统下默认已经安装了rsync,只需进行配置,并开启rsync守候进程即可。
配置同步目标服务器rsync
在多台目标服务器上配置如下(11、12、13都是同样的配置):
================================
vi /etc/rsyncd.conf
uid=root
gid=root
max connections=36000
use chroot=no
log file=/var/log/rsyncd.log
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
[tongbu1]
path=/opt/tongbu1
comment = xoyo video files
ignore errors = yes
read only = no
hosts allow = 192.168.1.10/24
hosts deny = *
================================
上面配置文件,表明允许主服务器(假设ip为192.168.1.10)访问,rsync同步模块名为[tongbu1],将同步过来的文件放入path指定的目录/opt/tongbu1。如果有多台从服务器,则每一台都需要进行类似的rsync配置,上面的uid gid要换成您服务器的相应用户,主意rysnc要有对被同步目录的操作权限。
配置好之后,使用如下命令,开启rsync守护进程:
#rsync –daemon
在主服务器上安装配置sresync 在google code下载sersync的可执行文件版本,里面有配置文件与可执行文件,这里用sersync2.5进行说明,新版本配置形式类似。 1.在主服务器上开启sersync守护进程,使sersync在后台运行,开启实时同步。 ./sersync -d ================================= [root@localhost GNU-Linux-x86]#ls confxml.xml sersync2 一、运行 要注意的是:sersync调用rsync执行任务,所以他依赖系统的PATH变量来找到rsync命令,而在linux中,初始化的PATH变量是不含有/usr/local/bin目录的(很不幸,如果你升级了rsync的话,他会默认装到这个目录),所以,你需要在/usr/bin/中给rsync创建一个link,符号的就可以: 二、附录:启动参数举例 也可以不进行同步,只运行插件:./sersync -m pluginName 多个参数可以配合使用 修改可监控的最大目录数量: echo 50000000 > /proc/sys/fs/inotify/max_user_watches
过程如下:
修改同步主服务器的配置文件:
#vi confxml.xml
只修改下面内容即可:
<sersync>
<localpathwatch=“/opt/tongbu1”>
<remoteip=“192.168.1.11”name=“tongbu1”/>
<remoteip=“192.168.1.12”name=“tongbu1”/>
<remoteip=“192.168.1.13”name=“tongbu1”/>
</localpath>
<crontabstart=“true”schedule=“30”/>
<pluginname=“refreshCDN”start=“true”/>
</sersync>
[root@localhost GNU-Linux-x86]# ./sersync2 -d
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
daemon thread num: 10
parse xml config file
host ip : localhost host port: 8008
config xml parse success
please set /etc/rsyncd.conf max connections=0 Manually
sersync working thread 12 = 1(primary thread) + 1(fail retry thread) + 10(daemon sub threads)
please according your cpu ,use -n param to adjust the cpu rate
run the sersync:
watch path is: /opt/tongbu
表明,sersync已经开启,可以在本地监控路径下建立文件,查看远程是否同步成功。
更详细的配置可看:sersync2 完全安装配置说明(二) —-可选功能与xml高级配置
=================================
2.在开启实时监控的之前对主服务器目录与远程目标机目录进行一次整体同步
[root@localhost GNU-Linux-x86]#./sersync -r
如果需要将sersync运行前,已经存在的所有文件或目录全部同步到远程,要以-r参数运行sersync,将本地与远程整体同步一次。
如果设置了过滤器,即在xml文件中,filter为true,则暂时不能使用-r参数进行整体同步。-r参数将会无效。
3.查看启动参数帮助
./sersync –help
4.指定配置文件
./sersync -o XXXX.xml
对于sersync使用可执行文件目录下的默认配置文件confxml.xml,如果需要使用另一个配置文件,可以使用-o参数指定其它配置文件。
5.指定默认的线程池的线程总数
./sersync -n num
6.不进行同步,只运行插件
./sersync -m pluginName
例如./sersync -m command,则在监控到文件事件后,不对远程目标服务器进行同步,而是直接运行command插件。
7.多个参数可以配合使用
./sersync -n 8 -o abc.xml -r -d
表示,设置线程池工作线程为8个,指定abc.xml作为配置文件,在实时监控前作一次整体同步,以守护进程方式在后台运行。
8.通常情况下,对本地到远程整体同步一遍后,在后台运行实时同步。
./sersync -d
=======================================
在另一篇文章中看到的相关命令:
1、执行命令:./sersync2 -r -d 启动sersync
r是先执行一遍完整同步,d是后台运行,稍后介绍所有启动参数。
2、加入sersync开机自动启动,老办法:/etc/rc.local,或者写一个service脚本加入chkconfig
cd /usr/bin
ln -s /usr/local/bin/rsync rsync
还有一个要注意的地方是:如果你的服务器网卡需要与交换机进行端口协商,不是立即接通,那么,最好在sersync启动以前,sleep一会儿,比如十秒,否则,rsync会因为找不到同步目的方而不工作。
1、/usr/local/sersync/sersync2 -r -d -o /usr/local/sersync/config.xml
#通常情况下使用这种方式,对本地到远程整体同步一遍后,在后台运行实时同步。
2、/usr/local/sersync/sersync2 -d -o /usr/local/sersync/config.xml
#在主服务器上开启sersync守护进程,使sersync在后台运行,开启实时同步。
3、/usr/local/sersync/sersync2 -r -o /usr/local/sersync/config.xml
#在开启实时监控的之前对主服务器目录与远程目标机目录进行一次整体同步
(如果设置了过滤器,即在xml文件中,filter为true,则暂时不能使用-r参数进行整体同步。-r参数将会无效)
4、/usr/local/sersync/sersync2 -n 5 -d -o /usr/local/sersync/config.xml
#指定默认的线程池的线程总数,如果不指定,默认启动线程池数量是10(适用于四核服务器)
#如果cpu使用过高,可以通过这个参数调低,如果机器配置较高,可以用-n跳高线程总数。
例如./sersync -m command,则在监控到文件事件后,不对远程目标服务器进行同步,而是直接运行command插件。
./sersync -n 8 -o abc.xml -r -d
表示,设置线程池工作线程为8个,指定abc.xml作为配置文件,在实时监控前作一次整体同步,以守护进程方式在后台运行。
XML配置说明
[root@localhost /data/test]#vi /home/like/software/GNU-Linux-x86/confxml.xml
sersync可选功能是通过xml配置文件来实现的,基本配置文件如下:
——————————————————————————————————————————————
01<?xml version=”1.0″ encoding=”ISO-8859-1″?>
02<headversion=“2.5”>
03 <hosthostip=“localhost”port=“8008”></host>
04 <filterstart=“false”>
05 <excludeexpression=“(.*)\.gz”></exclude>
06 <excludeexpression=“^info/*”></exclude>
07 </filter>
08 <inotify>
09 <deletestart=“true”/>
10 <createFolderstart=“true”/>
<createFilestart=“true”/>
11 </inotify>
12 <debugstart=“false”/>
13 <sersync>
14 <localpathwatch=“/opt/tongbu1”>
15 <remoteip=“192.168.1.11”name=“tongbu1”/>
16 <!–<remote ip=”192.168.1.12″ name=”tongbu”/>–>
17 <!–<remote ip=”192.168.1.13″ name=”tongbu”/>–>
18 </localpath>
19 <rsync>
20 <commonParams params=”-artuz“/>
20 <authstart=“false”users=“root”passwordfile=“/etc/rsync.pas”/>
21 <userDefinedPortstart=“false”port=“874”/><!– port=874 –>
22 <timeoutstart=“false”time=“100”/><!– timeout=100 –>
23 <sshstart=“false”/>
24 </rsync>
25 <failLogpath=“/tmp/rsync_fail_log.sh”timeToExecute=“60”/><!–default every 60min execute once–>
26 <crontabstart=“false”schedule=“600”><!–600mins–>
27 <crontabfilterstart=“false”>
28 <excludeexpression=“*.gz”></exclude>
29 <excludeexpression=“info/*”></exclude>
30 </crontabfilter>
31 </crontab>
32 <pluginstart=“false”name=“command”/>
33 </sersync>
——————————————————————————————————————————————
下面做逐行的进行解释说明:
03 <hosthostip=“localhost”port=“8008”></host>
hostip与port是针对插件的保留字段,对于同步功能没有任何作用,保留默认即可。
filter文件过滤功能
对于sersync监控的文件,会默认过滤系统的临时文件(以“.”开头,以“~”结尾),除了这些文件外,可以自定义其他需要过滤的文件。
04 <filterstart=“true”>
05 <excludeexpression=“(.*)\.gz”></exclude>
06 <excludeexpression=“^info/*”></exclude>
07 </filter>
将start设置为 true,在exclude标签中,填写正则表达式,默认给出两个例子分别是过滤以”.gz”结尾的文件与过滤监控目录下的info路径(监控路径/info/*),可以根据需要添加,但开启的时候,自己测试一下,正则表达式如果出现错误,控制台会有提示。相比较使用rsync 的exclude功能,被过滤的路径,不会加入监控,大大减少rsync的通讯量。
inotify监控参数设定(优化)
对于inotify监控参数可以进行设置,根据您项目的特点优化srsync。
08 <inotify>
09 <deletestart=“true”/>
10 <createFolderstart=“true”/>
11 <createFilestart=“true”/>
12 </inotify>
对于大多数应用,可以尝试把createFile(监控文件事件选项)设置为false来提高性能,减少 rsync通讯。因为拷贝文件到监控目录会产生create事件与close_write事件,所以如果关闭create事件,只监控文件拷贝结束时的事 件close_write,同样可以实现文件完整同步。
注意:强将createFolder保持为true,如果将createFolder设为false,则不会对产生的目录进行监控,该目录下的子文件与子目录也不会被监控。所以除非特殊需要,请开启。
默认情况下对创建文件(目录)事件与删除文件(目录)事件都进行监控,如果项目中不需要删除远程目标服务器的文件(目录),则可以将delete 参数设置为false,则不对删除事件进行监控。
Debug开启
12 <debugstart=“false”/>
设置为true,开启debug模式,会在sersync正在运行的控制台,打印inotify事件与rsync同步命令。
XFS文件系统
<fileSystem xfs=“false”/>
对于xfs文件系统的用户,需要将这个选项开启,才能使sersync正常工作
文件监控与远程同步设置
3 <sersync>
14 <localpathwatch=“/opt/tongbu1”>
15 <remoteip=“192.168.1.11“name=“tongbu1”/>
16 <!–<remote ip=”192.168.1.12″ name=”tongbu”/>–>
17 <!–<remote ip=”192.168.1.13″ name=”tongbu”/>–>
18 </localpath>
详见:sersync2 完全安装配置说明(一) —-基本功能使用
Rsync参数配置
19 <rsync>
20 <commonParams params=”-artuz“/>
20 <authstart=“false”users=“root”passwordfile=“/etc/rsync.pas”/>
21 <userDefinedPortstart=“false”port=“874”/><!– port=874 –>
22 <timeoutstart=“false”time=“100”/><!– timeout=100 –>
23 <sshstart=“false”/>
24 </rsync>
commonParams可以用户自定义rsync参数,默认是-artuz
authstart=“false” 设置为true的时候,使用rsync的认证模式传送,需要配置user与passwrodfile(–password-file=/etc/rsync.pas),来使用。userDefinedPort 当远程同步目标服务器的rsync端口不是默认端口的时候使用(–port=874)。timeout设置rsync的timeout时间(–timeout=100)。ssh使用rsync -e ssh的方式进行传输。
失败日志脚步配置
25 <failLogpath=“/tmp/rsync_fail_log.sh”timeToExecute=“60”/><!–default every 60min
对于失败的传输,会进行重新传送,再次失败就会写入rsync_fail_log,然后每隔一段时间(timeToExecute进行设置)执行该脚本再次重新传送,然后清空该脚本。可以通过path来设置日志路径。
Crontab定期整体同步功能
26 <crontabstart=“false”schedule=“600”><!–600mins–>
27 <crontabfilterstart=“false”>
28 <excludeexpression=“*.gz”></exclude>
29 <excludeexpression=“info/*”></exclude>
30 </crontabfilter>
31 </crontab>
crontab可以对监控路径与远程目标主机每隔一段时间进行一次整体同步,可能由于一些原因两次失败重传都失败了,这个时候如果开启了crontab功能,还可以进一步保证各个服务器文件一致,如果文件量比较大,crontab的时间间隔要设的大一些,否则可能增加通讯开销。schedule这个参数是设置crontab的时间间隔,默认是600分钟
如果开启了filter文件过滤功能,那么crontab整体同步也需要设置过滤,否则虽然实时同步的时候文件被过滤了,但crontab整体同步的时候如果不单独设置crontabfilter,还会将需过滤的文件同步到远程,crontab的过滤正则与filter过滤的不同,也给出了两个实例分别对应与过滤文件与目录。总之如果同时开启了filter与crontab,则要开启crontab的crontabfilter,并按示例设置使其与filter的过滤一一对应。
插件设置
32 <pluginstart=“false”name=“command”/>
当设置为true的时候,将文件同步到远程服务器后会调用name参数指定的插件。详见请看
插件设置。
插件相关xml<sersync>
……
<pluginstart=“false”name=“command”/>
</sersync>
<pluginname=“command”>
<paramprefix=“/bin/sh”suffix=“”ignoreError=“true”/>
<filterstart=“false”>
<includeexpression=“(.*)\.php”/>
<includeexpression=“(.*)\.sh”/>
</filter>
</plugin>
<pluginname=“socket”>
<localpathwatch=“/opt/tongbu”>
<deshostip=“192.168.138.20”port=“8009”/>
</localpath>
</plugin>
<pluginname=“refreshCDN”>
<localpathwatch=“/data0/htdocs/cms.88181.com/site/”>
<cdninfodomainname=“ccms.chinacache.com”port=“80”username=“xxxx”passwd=“xxxx”/>
<sendurlbase=“http://pic.88181.com/cms”/>
<regexurlregex=“false”match=“cms.88181.com/site([/a-zA-Z0-9]*).88181.com/images”/>
</localpath>
</plugin>
如 上面的xml所示,其中plugin标签设置为true时候,在同步文件或路径到远程之后后,调用插件。通过name参数指定需要执行的插件。目前支持的有command refreshCDN socket http四种插件。http插件目前由于兼容性原因去除,以后会重新加入。
command插件当文件同步完成后,会调用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为ture,include可以只对正则匹配到的文件,调用command。
刷新CDN插件“refreshCDN”,就在同步过程中将文件发送到目 的服务器后刷新cdn接口。如果不想使用,则将start属性设为false即可。如果需要使用其他插件,则查看其他plugin标签,将插件名称改为 xml中其它插件的名称即可。
以下模块(refreshCDN http socket)可以单独使用,只需在命令行下使用-m 参数即可。如果需要作为插件与同步程序一起使用,见同步程序说明的插件配置。
该模块根据chinaCDN的协议,进行设计,当有文件产生的时候,就向cdn接口发送需要刷新的路径位置。刷新CDN模块需要配置的xml文件如下。
<pluginname=“refreshCDN”>
<localpathwatch=“/data0/htdocs/cms.88181.com/site/”>
<cdninfodomainname=“ccms.chinacache.com”port=“80”username=“xxxx”passwd=“xxxx”/>
<sendurlbase=“http://pic.88181.com/cms”/>
<regexurlregex=“false”match=“cms.88181.com/site([/a-zA-Z0-9]*).88181.com/images”/>
</localpath>
</plugin>
其中 localpath watch 是需要监控的目录。
cdnifo标签制定了cdn接口的域名,端口号,以及用户名与密码。
sendurl标签是需要刷新的url的前缀。
regexurl标签中的,regex属性为true时候,使用match属性的正则语句匹配inotify返回的路径信息,并将正则匹配到的部分作为url一部分,
举例:
如果产生文件事件为:/data0/htdoc/cms.88181.com/site/jx3.88181.com/image/a/123.txt
经过上面的match正则匹配后,最后刷新的路径是:
http://pic.88181.com/cms/jx3/a/123.txt;
如果regex属性为false,最后刷新的路径是
http://pic.88181.com/cms/jx3.88181.com/images/a/123.txt;
socket插件
socket插件,开启该模块,则向指定ip与端口发送inotify所产生的文件路径信息:
Http插件
http插件,可以向指定域名的主机post,inotify监控的事件
其中mask是事件掩膜,8为修改保存,其它inotify事件掩码,见google。
单独运行插件
插件也可以单独使用,即不对远程目标机进行同步,直接调用插件:
只调用command插件
./sersync -d -m command
只调用refreshCDN插件
./sersync -d -m refreshCDN
只调用socket插件
./sersync -d -m socket
只调用http插件
./sersync -d -m http
首先下载安装boost c++库。
可以到官方下载,也可以从如下地址下载,使用前安装boost依赖库,icu用来解决编码问题。
wget http://johntech-resource.googlecode.com/files/icu4c-4_0_1-src.tgz
cd icu/source
./configure –prefix=/usr
make && make install
wget http://johntech-resource.googlecode.com/files/boost_1_44_0.tar.bz2
tar jxvf boost_1_44_0.tar.bz2
cd boost_1_44_0
./bootstrap.sh
./bjam -sHAVE_ICU=1
./bjam install
新安装的文件会被安装到/usr/local的相应目录下。这个目录会在netbeans项目中配置,其它IDE环境配置方式请参考IDE相应文档。
下载安装NETBEANS开发环境,请注意下载c/c++版本
下载地址:http://netbeans.org/downloads/index.html
chmod +x netbeans-6.9.1-ml-cpp-linux.sh
./netbeans-6.9.1-ml-cpp-linux.sh
下载sersync 项目源码包。
wget http://sersync.googlecode.com/files/sersync2.5_source.tar.gz
tar zxvf sersync2.5_source.tar.gz
使用netbeans打开sersync路径下的项目即可直接编译运行,具体测试环境搭建在本地测试需要配合
rsync配置文件,和本地监控目录。具体详见:http://www.linuxidc.com/Linux/2012-02/53572p2.htm