rsync+sersync实现两端实时同步

摘要

提到数据同步就必然会谈到rsync,一般简单的服务器数据传输会使用ftp/sftp等方式,但是这样的方式效率不高,不支持差异化增量同步也不支持实时传输。针对数据实时同步需求大多数人会选择rsync+inotify-tools的解决方案,但是这样的方案也存在一些缺陷(文章中会具体指出),sersync是国人基于前两者开发的工具,不仅保留了优点同时还强化了实时监控,文件过滤,简化配置等功能,帮助用户提高运行效率,节省时间和网络资源。

可靠高效的数据实时同步方式

在同步服务器上开启sersync,将监控路径中的文件同步到目标服务器,因此需要在同步服务器,也就是数据源配置sersync,在同步目标服务器配置rsync。

sersync利用inotify与rsync对服务器进行实时同步,其中inotify用于监控文件系统事件,rsync是目前广泛使用的同步算法,其优点是只对文件不同的部分进行操作,所以其优势大大超过使用挂接文件系统的方式进行镜像同步。

sersync由金山的周洋开发完成,是目前使用较多的文件同步工具之一。该工具和其他的工具相比有如下优点:

  • sersync是使用c++编写,由于只同步发生更改的文件,因此比其他同步工具更节约时间、带宽;
  • 安装方便、配置简单;
  • 使用多线程进行同步,能够保证多个服务器实时保持同步状态;
  • 自带出错处理机制,通过失败队列对出错的文件重新出错,如果仍旧失败,则每10个小时对同步失败的文件重新同步;
  • 自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次;
  • 自带socket与http协议扩展,你可以方便的进行二次开发;

img

阅读原文 - http://wsgzao.github.io/post/sersync/

扩展阅读

基于rsync+sersync的服务器文件同步实战 - http://www.markdream.com/technologies/server/syncfile-by-rsync.shtml
通过 rsync sersync 实现高效的数据实时同步架构 - https://www.cnhzz.com/rsync_sersync/
rsync - https://rsync.samba.org/
inotify-tools - https://github.com/rvoicilas/inotify-tools
sersync - http://code.google.com/p/sersync/

环境

单方面同步

  • 192.168.115.129 同步端
  • 192.168.115.135 数据源

双向同步

  • 192.168.115.129 同步端&数据源
  • 192.168.115.135 数据源&同步端

同步端配置rsync

img

在192.168.115.129机器上配置好rsync同步模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
yum install -y rsync
vim /etc/rsyncd.conf
uid = root
gid = root
port = 873
max connections = 64
read only = no
use chroot = no
timeout = 600
hosts allow = 192.168.115.135
hosts deny = *
log file = /data/logs/rsyncd.log
pidfile = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
secrets file = /etc/rsync.pass
motd file = /etc/rsyncd.Motd
auth users = rsync
[rsyncftp]
path = /data/ftp
comment = rsyncftp
ignore errors
list = no

启动rsync

1
2
3
echo "rsync:rsync@123" > /etc/rsync.pass
chmod 600 /etc/rsync.pass
rsync --daemon --config=/etc/rsyncd.conf

在192.168.115.135做测试

1
2
3
4
5
echo "rsync@123" > /etc/rsync.pass
chmod 600 /etc/rsync.pass
mkdir /data/ftp
touch /data/ftp/test
rsync -avz --delete --progress /data/ftp/ rsync@192.168.115.129::rsyncftp --password-file=/etc/rsync.pass

数据源做sersync2

下载安装sersync2

1
2
3
4
wget https://github.com/wsgzao/sersync/raw/master/sersync2.5.4_64bit_binary_stable_final.tar.gz
tar xvf sersync2.5.4_64bit_binary_stable_final.tar.gz
cp GNU-Linux-x86/sersync2 /usr/local/bin
cp GNU-Linux-x86/confxml.xml /etc

修改sersync2配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
vim /etc/confxml.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
# 设置本地ip以及端口
<host hostip="localhost" port="8008"></host>
# 是否开启debug
<debug start="false"/>
# 是否开启xfs系统
<fileSystem xfs="false"/>
# 同步时忽略推送的文件(正则表达式),默认关闭
<filter start="false">
<exclude expression="(.*)\.svn"></exclude>
<exclude expression="(.*)\.gz"></exclude>
<exclude expression="^info/*"></exclude>
<exclude expression="^static/*"></exclude>
</filter>
# 设置要监控的事件
<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>
<sersync>
# 本地同步的目录路径
<localpath watch="/data/ftp">
# 远程IP和rsync模块名,可以写多个
<remote ip="192.168.115.129" name="rsyncftp"/>
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
# rsync指令参数
<commonParams params="-artuz"/>
# rsync同步认证
<auth start="true" users="rsync" passwordfile="/etc/rsync.pass"/>
# 设置rsync远程服务端口,远程非默认端口则需打开自定义
<userDefinedPort start="false" port="873"/><!-- port=874 -->
# 设置超时时间
<timeout start="false" time="100"/><!-- timeout=100 -->
# 设置rsync+ssh加密传输模式,默认关闭,开启需设置SSH加密证书
<ssh start="false"/>
</rsync>
# sersync传输失败日志脚本路径,每隔60会重新执行该脚本,执行完毕会自动清空。
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
# 设置rsync+crontab定时传输,默认关闭
<crontab start="false" schedule="600"><!--600mins-->
<crontabfilter start="false">
<exclude expression="*.php"></exclude>
<exclude expression="info/*"></exclude>
</crontabfilter>
</crontab>
# 设置sersync传输后调用name指定的插件脚本,默认关闭
<plugin start="false" name="command"/>
</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>
# 插件脚本范例
<plugin name="socket">
<localpath watch="/opt/tongbu">
<deshost ip="192.168.138.20" port="8009"/>
</localpath>
</plugin>
<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>
</head>

启动sersync2

1
2
3
4
5
6
sersync2 -r -d -o /etc/confxml.xml
-r 开启实时监控之前做一次整体同步
-d 后台运行
-o 指定配置文件
-n 指定线程
-m 不运行同步,只运行插件

另一端配置

在192.168.115.135机器上配置好rsync同步模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
yum install -y rsync
vim /etc/rsyncd.conf
uid = root
gid = root
port = 873
max connections = 64
read only = no
use chroot = no
timeout = 600
hosts allow = 192.168.115.129
hosts deny = *
log file = /data/logs/rsyncd.log
pidfile = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
motd file = /etc/rsyncd.Motd
secrets file = /etc/rsync.passt
auth users = rsync
[rsyncftp]
path = /data/ftp
comment = rsyncftp
#ignore errors
#list = no

启动rsync

1
2
3
echo "rsync:rsync@123" > /etc/rsync.passt
chmod 600 /etc/rsync.passt
rsync --daemon --config=/etc/rsyncd.conf

在192.168.115.129做测试

1
2
3
4
5
echo "rsync@123" > /etc/rsync.passt
chmod 600 /etc/rsync.passt
mkdir /data/ftp
touch /data/ftp/test1
rsync -avzR --delete --progress /data/ftp/ rsync@192.168.115.135::rsyncftp --password-file=/etc/rsync.passt

修改sersync2配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
vim /etc/confxml.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
# 设置本地ip以及端口
<host hostip="localhost" port="8008"></host>
# 是否开启debug
<debug start="false"/>
# 是否开启xfs系统
<fileSystem xfs="false"/>
# 同步时忽略推送的文件(正则表达式),默认关闭
<filter start="false">
<exclude expression="(.*)\.svn"></exclude>
<exclude expression="(.*)\.gz"></exclude>
<exclude expression="^info/*"></exclude>
<exclude expression="^static/*"></exclude>
</filter>
# 设置要监控的事件
<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>
<sersync>
# 本地同步的目录路径
<localpath watch="/data/ftp">
# 远程IP和rsync模块名,可以写多个
<remote ip="192.168.115.135" name="rsyncftp"/>
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
# rsync指令参数
<commonParams params="-artuz"/>
# rsync同步认证
<auth start="true" users="rsync" passwordfile="/etc/rsync.passt"/>
# 设置rsync远程服务端口,远程非默认端口则需打开自定义
<userDefinedPort start="false" port="873"/><!-- port=874 -->
# 设置超时时间
<timeout start="false" time="100"/><!-- timeout=100 -->
# 设置rsync+ssh加密传输模式,默认关闭,开启需设置SSH加密证书
<ssh start="false"/>
</rsync>
# sersync传输失败日志脚本路径,每隔60会重新执行该脚本,执行完毕会自动清空。
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
# 设置rsync+crontab定时传输,默认关闭
<crontab start="false" schedule="600"><!--600mins-->
<crontabfilter start="false">
<exclude expression="*.php"></exclude>
<exclude expression="info/*"></exclude>
</crontabfilter>
</crontab>
# 设置sersync传输后调用name指定的插件脚本,默认关闭
<plugin start="false" name="command"/>
</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>
# 插件脚本范例
<plugin name="socket">
<localpath watch="/opt/tongbu">
<deshost ip="192.168.138.20" port="8009"/>
</localpath>
</plugin>
<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>
</head>

启动sersync2

1
2
3
4
5
6
sersync2 -r -d -o /etc/confxml.xml
-r 开启实时监控之前做一次整体同步
-d 后台运行
-o 指定配置文件
-n 指定线程
-m 不运行同步,只运行插件

双向同步完成

进行测试

192.168.115.129

1
2
cd /data/ftp
for i in `seq 1 20`;do dd if=/dev/zero of=$i bs=1024k count=10 ;done

192.168.115.135

1
2
cd /data/ftp
for i in `seq 21 40`;do dd if=/dev/zero of=$i bs=1024k count=10 ;done

在两端查看文件同步结果

测试完成