一、项目介绍
Sersync项目利用inotity与rsync技术实现对服务器数据实时同步的解决方案,其中inotity用于监控sersync所在服务器上的文件变化。
Sersync项目的优点:
1. 相比较单纯的inotity工具,sersync是使用C++编写的,对linux系统文件产生的临时文件和重复的文件操作有过滤功能,在结合rsync的时候,会减少运行时消耗的本地及网络资源,速度快。
2.配置简单
3.使用多线程进行同步(即可以并发同步多个不同的文件),尤其在同步较大的文件时,能够保证多个服务器实时保持同步状态。
4.sersync自带出错处理机制,通过失败 队列对出错的文件重新同步,还出错,每10个小时再来一遍。
5.sersync自带crontab功能,只需在xml配置中开启,就可以同步。
6.sersync自动socket与http的协议扩展,可满足二次开发需求。
二、基本框架
三、 设计简析
1.线程组线程是等待线程对立的守护线程,当事件队列中有数据产生的时候,线程组守护线程就会逐个唤醒同步线程,当队列中inotify事件较多的时候,同步线程就会被全部唤醒一起工作。这样设计的目的是能够同时处理多个inotify事件,从而提升服务器的并发同步能力。之所以称之为线程组线程,是因为每个线程在工作的时候,会根据服务器上新写入文件的数量建立子线程,子线程可以保证所有的文件与各个服务器同时同步,当要同步的文件较大的时候,这样的设计可以保证各个远程服务器可以同事获得要同步的文件。
2.服务器线程的作用有三个(保证主服务器和从服务器数据一致且实时):
2.1 处理同步失败的文件,将这些文件再次同步,对于再次同步失败的文件会生成rsync_fail_log.sh脚本,记录失败的事件
2.2 同时每个10小时执行脚本一次,同时清空脚本。
2.3 还有就是crontab功能,可以每隔一定事件,将所有路径整体同步一次。
3.过滤队列的建立是为了过滤短时间内产生的重复的inotify信息,例如在删除文件夹的时候,inotify就会同事产生删除文件夹里的文件与删除文件夹的事件,通过过滤队列,当删除文件夹时间产生的时候,会将之前加入队列的删除文件的事件全部过滤掉,这样只产生一条删除文件夹事件,从而减轻了同步的负担。同时对于修改文件的操作的时候,会产生临时文件的重复操作。
四、sersync安装配置
4.1 sersync同步需求逻辑图
当前版本的sersync依赖于rsync进行数据同步,如下图所示,在同步主服务器(Master)上开启sersync,sersync负责监控配置路径中的文件系统事件变化,然后调用rsync命令把更新的文件同步到目标服务器(Slave),因此,需要在主服务器配置sersync,在同步目标服务器配置rsync server(注意:是rsync服务器)
如图所示,用户会实时网左边的同步主服务器(M)上写入或更新文件数据,此时需要在左边的同步服务器(M)上配置sersync服务,在右边的同步目标服务器S1和S2服务器上配置rsync守护进程,这样在主服务器M上产生的写入或更新的文件就会被sersync服务实时的同步到多个目标服务器(S1,S2等)。一般的Linux服务器一般安装了rsync软件,因此在主服务器(M)上有rsync命令即可,在目标服务器(S1、S2)上只需要进行简单的配置,并开启rsync守候进程即可。
4.2安装环境准备
角色 | 服务器配置 | IP | 机器名 | |
---|---|---|---|---|
sersync服务(M) | VM | 192.168.0.103 | djw | |
rsync服务(S1) | VM | 192.168.0.100 | djw1 | |
rsync服务(S2) | VM | 192.168.0.104 | djw2 |
4.3 配置同步服务器
部署总结:
步骤一、 配置slave上的rsync服务
步骤二、 配置master上sersync客户端
4.3.1 slave上部署rsync服务
本次测试使用的服务器为djw1和djw2 server,即IP为192.168.0.100,192.168.0.104
vim /etc/rsyncd.conf
写入如下测试内容:
# Minimal configuration file for rsync daemon
# See rsync(1) and rsyncd.conf(5) man pages for help
# This line is required by the /etc/init.d/rsyncd script # GLOBAL OPTIONS uid = root gid = root use chroot = no read only = false #limit access to private LANs hosts allow=192.168.0.0/24 hosts deny=* ignore errors max connections = 2000 pid file = /var/run/rsyncd.pid auth users = rsync_backup secrets file = /etc/rsyncd.password #lock file = /var/run/rsync.lock motd file = /etc/rsyncd/rsyncd.motd #This will give you a separate log file log file = /var/log/rsync.log #This will log every file transferred - up to 85,000+ per user, per sync transfer logging = yes log format = %t %a %m %f %b syslog facility = local3 timeout = 300 # MODULE OPTIONS [bbs] comment = bbs by www 2015年10月27日15:53:24 path = /var/www/html/bbs [blog] comment = blog by www 2015年10月27日15:53:24 path = /var/www/html/blog
上面的rsync服务的配置文件表明允许sersync主服务器(IP为192.168.0.103)访问,rsync同步模块名为[bbs],[blog]将同步过来的文件分别放入
对应的path指定的目录 /var/www/html/bbs,/var/www/html/blog下,如果有多台目标服务器,则每台都需要进行类似的rsync服务配置,上面的
uid,gid要换成本服务器对应的同步用户。注意rsync服务账户(上述用了root用户)要有对被同步目录(/var/www/html)的写入更新权限。
创建待同步的目录
[root@li-centos6.5 /var/www] # mkdir -p /var/www/html/bbs /var/www/html/blog [root@li-centos6.5 /var/www] # tree /var/www/html /var/www/html ├── bbs └── blog # 此步骤在djw1,djw2 上都要执行,否则,rsync服务会因为没有path路径而无法启动。
置相关权限认证echo "rsync_backup:123456">/etc/rsyncd.password
chmod 600 /etc/rsyncd.password # order for check cat /etc/rsyncd.password ll /etc/rsyncd.password
配置好后,使用下面的命令开启rsync守护进程
rsync --daemon
ps -ef|grep rsync
netstat -tunpl|grep :873
配置开机自启动echo "/usr/bin/rsync --daemon">>/etc/rc.local
grep demoan /etc/rc.local
4.3.2
master上配置rsync客户端(Master操作)
4.3.2.1master上配置rsync权限
在master(192.168.0.100)上配置rsync客户端相关权限echo '123456' > /etc/rsync.password
chmod 600 /etc/rsync.password cat /etc/rsync.password ll /etc/rsync.password
4.3.2.2master上手工测试rsync同步情况(
此步骤非常关键且重要,如果这里测试都不成功,后面的sersync配好也不会同步数据
)
1. 分别创建待同步数据
touch /var/www/html/bbs/bbs.log /var/www/html/blog/blog.log
tree /var/www/html/
2. 执行同步命令(操作之前停用防火墙)
rsync -avz /var/www/html/bbs/ rsync_backup@192.168.0.101::bbs/ --password-file=/etc/rsync.password
rsync -avz /var/www/html/bbs/ rsync_backup@192.168.0.104::bbs/ --password-file=/etc/rsync.password
rsync -avz /var/www/html/blog/ rsync_backup@192.168.0.101::blog/ --password-file=/etc/rsync.password
rsync -avz /var/www/html/blog/ rsync_backup@192.168.0.104::blog/ --password-file=/etc/rsync.password
同步完后,可以到两台slave服务器上查看结果,如下:
[root@li-centos6.5 /var/www/html]
# tree /var/www/html # 检查目录和文件同步情况 ├── bbs │ └── bbg.log └── blog └── blog.log [root@li-centos6.7 /var/www/html] # tree /var/www/html. # 检查目录和文件同步情况 ├── bbs │ └── bbg.log └── blog └── blog.log
4
.3.3 master上配置rsync客户端
4.3.3.1 下载sersync
下载sersync的可执行文件版本,里面有配置文件和可执行文件,如下:cd /usr/local/src && http://down.whsir.com/downloads/sersync2.5.4_64bit_binary_stable_final.tar.gz
4.3.3.2 安装sersync
tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz
mv GNU-Linux-x86 /usr/local/sersync
tree /usr/local/sersync/
/usr/local/sersync/
├── confxml.xml
└── sersync2
4.3.3.3 规范sersync目录结构(非必须)
cd /usr/local/sersync/ && mkdir conf bin logs mv confxml.xml ./conf/. && mv sersync2 ./bin/sersync tree /usr/local/sersync[root@djw sersync]# tree /usr/local/sersync
/usr/local/sersync
├── bin
│ └── sersync
├── conf
│ └── confxml.xml
└── logs
4.3.3.4 配置sersync# /bin/cp conf/confxml.xml conf/confxml.xml.luo.$(date +%F) # 备份配置文件
[root@djw sersync]# tree conf/
conf/
├── confxml.xml
└── confxml.xml.luo.2019-06-20
初始化的配置文件内容如下:
[root@djw conf]# cat -n confxml.xml
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <head version="2.5">
3 <host hostip="localhost" port="8008"></host>
4 <debug start="false"/>
5 <fileSystem xfs="false"/>
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>
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>
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>
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>
36 <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
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>
43 <plugin start="false" name="command"/>
44 </sersync>
45
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>
53
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>
65 </plugin>
66 </head>
1) 修改24~28行的内容
24 <localpath watch="/opt/tongbu"> # 定义本地要同步的目录
25 <remote ip="127.0.0.1" name="tongbu1"/> # 定义要同步的服务器IP和模块名(例如上述的blog、bbs)
26 <!--<remote ip="192.168.8.39" name="tongbu"/>-->
27 <!--<remote ip="192.168.8.40" name="tongbu"/>-->
28 </localpath>
修改后如下:
<localpath watch="/var/www/html/blog"> # 定义本地要同步的目录
<remote ip="192.168.0.100" name="blog"/> # 定义要同步的服务器IP和模块名(例如上述的blog、bbs)
<remote ip="192.168.0.104" name="blog"/>
</localpath>
<localpath watch="/var/www/html/bbs"> # 定义本地要同步的目录
<remote ip="192.168.0.100" name="bbs"/> # 定义要同步的服务器IP和模块名(例如上述的blog、bbs)
<remote ip="192.168.0.104" name="bbs"/>
2) 修改31~34行(认证部分)
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"/>
修改后的内容如下:
<auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/> <!--slave服务器的用户名-->
<userDefinedPort start="false" port="874"/><!-- port=874 -->
<timeout start="true" time="100"/><!-- timeout=100 -->
<ssh start="false"/>
3) 修改36~37行36 <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
修改后的内容如下:
36 <failLog path="/usr/local/sersync/logs/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
当同步失败后,日志记录到/usr/local/sersync/logs/rsync_fail_log.sh
文件中,并且每60分钟对失败的log进行重新同步。
4.3.3.4 开启sersync守护进程同步数据
配置sersync环境变量
echo 'export PATH=/usr/local/sersync/bin:$PATH'>>/etc/profile
tail -1 /etc/profile
source /etc/profile
which sersync
启动sersync命令:sersync -r -d -o /usr/local/sersync/conf/confxml.xml
[root@djw conf]# sersync -r -d -o /usr/local/sersync/conf/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: -r rsync all the local files to the remote servers before the sersync work
option: -d run as a daemon
option: -o config xml name: /usr/local/sersync/conf/confxml.xml
daemon thread num: 10
parse xml config file
host ip : localhost host port: 8008
daemon start,sersync run behind the console
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)
Max threads numbers is: 32 = 12(Thread pool nums) + 20(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 /var/www/html/blog && rsync -artuz -R --delete ./ 192.168.0.101::blog >/dev/null 2>&1
测试结果:发现问题,多实例的情况下仅第一个模块的路径能同步,其他模块下面的路径不能同步。
sersync -r -d -o /usr/local/sersync/conf/confxml_bbs.xml
配置多实例的同步情况(针对多个模块同步的情况)
sersync –d –o /usr/local/serysnc/conf/blog_confxml.xml
sersync –d –o /usr/local/serysnc/conf/bbs_confxml.xml
… …
不同的config文件是将模块分开放置,即:4.3.3.3步骤中的第一步中的代码分开在几个不同的文件中,这样启动的时候指定模块同步。
将上述命令,写入/etc/rc.local中,随系统自启动
/bin/cp /etc/rc.local /etc/rc.local_luo_$(date +%F)
cat >>/etc/rc.local<<EOF
# sersync data to 192.168.0.101,192.168.1.102
sersync –d –o /usr/local/serysnc/conf/confxml_bbs.xml
sersync –d –o /usr/local/serysnc/conf/confxml_blog.xml
EOF
tail -3 /etc/rc.local
至此,已经完成了Master上对Slave1,Slave2上多实例(bbs,blog多模块)的同步。
五、最后,配置文件中的 /usr/local/serysnc/conf/confxml.xml逐行了解,可以百度网络上。
这里要说明一下:
1)sersync可选功能是通过xml配置文件来实现的
2)插件的定义:在现有软件上实现某个功能的时候,通过配置调用其他软件或者工具的功能,让其他软件在这个调用的时候执行其功能,这个软件在原软件上就叫做插件,表示插入的东东,嘿嘿!
3)在xml文件中的46行开始,都是插件的功能。