前言

对于数据的实时同步,例如:某些配置文件或web文件在集群中的同步,通常我们有几种方式:

使用网络raid(例如:nfs/drbd)将某些目录由源服务器挂载到目标服务器(由于网络raid严重依赖网络,尤其是处于不同的网络环境,当网络联通失败后,客户端挂载的网络磁盘会丢失,必须重新挂载。优点是可以将有大量文件的目录直接挂载过去,虚拟磁盘不占用目标服务器的空间。常用于同一内网环境下)

使用rsync/scp及其他的方式将源文件传输到对应的目标服务器的目录(需要将源文件进行传输,传输过程依赖网速,如果是大文件或大量小文件的传输,速度缓慢,占用目标服务器空间。常用方法:rsync+inotify-tools / rsync+sersync)

下面介绍的是 rsync+sersync实现数据的实时同步/传输。



rsync+Inotify-tools与rsync+sersync



Inotify-tools与sersync都是基于Inotify开发的用于辅助rsync传输的工具。

Inotify-tools仅记录下被监听的目录发生的变化,并没有把发生了变化的具体的文件或者目录记录下来,当它监听到目录变化时,会产生一个rsync进程(单线程),遍历后,开始同步整个目录,当目录数据量或小文件数较大时,同步耗时。配置较sersync复杂,还得添加脚本。

sersync可以记录下被监听目录中的发生变化的具体文件或目录,当它监听到目录下的文件变化时,会使用rsync(多线程)对发生变化的文件或目录进行同步,并且可以对传输失败的文件定时重传。配置简单。



Sersync+rsync 数据同步


本篇仅演示将A的数据传输到B and C的单向传输

A:源服务器    (sersync)   192.168.10.1
B:目标服务器1 (rsync)     192.168.10.2
C:目标服务器2 (rsync)     192.168.10.3

下列链接为rsync的基础操作:



【1】rsync安装配置


在目标服务器中执行



<1>安装rsync

yum -y install rsync


<2>配置rsync

cat /etc/rsyncd.conf 


uid = root                                   #设置运行rsync的用户为root,当设为其他用户,本地的目标目录必须有此用户的权限
gid = root                                   #设置运行rsync的用户组为root,当设为其他时,本地的目标目录必须有此用户的权限
#port = 873                                  #指定rsync的端口.可不配置,默认873
use chroot = no                              #是否锁定在家目录
max connections = 1000                       #最大连接数
pid file = /var/run/rsyncd.pid               #指定pid文件的存放位置
lock file = /var/run/rsync.lock              #指定支持max connections参数的锁文件
log file= /var/log/rsyncd_script.log         #指定日志文件,可自行配置
#hosts allow = 192.168.10.0/24               #允许进行数据同步的客户端IP地址;可以设置多个,用英文状态下逗号隔开;当使用*代表所有,用法等同于tcp_wrapper,可不配置
#hosts deny = 0.0.0.0/32                     #禁止数据同步的客户端IP地址;可以设置多个,用英文状态下逗号隔开;用法等同于tcp_wrapper,可不配置
timeout = 600                                #设置超时时间,单位 秒
ignore errors                                #忽略I/O等错误
read only = false                            #设置rsync服务端文件为读写权限
list = false                                 #不显示rsync服务端资源列表
auth users = rsyncback                       #指定认证用户。无需创建
secrets file = /etc/rsync.password           #指定认证用户的密码文件。可自行配置,名称任意

#上方为全局配置。如全局配置中未配置某些参数,可在下方各模块中按个人需求配置(例如:可为每个模块配置一个日志文件,认证用户,认证密码文件,连接数等)

[back1]                                      #[]内为模块名(名称任意,但必须唯一),通常一个模块代表一个目录
comment = back1                              #注释,通常任意,可为this is ...
path = /root/jiema/                          #该模块代表的目标服务器中的目录,目标服务其中必须有此目录,且上方指定的uid,gid必须有此目录权限

[back2]                                      #[]内为模块名(名称任意,但必须唯一)
comment = back2                              #注释,通常任意,可为this is ...
path = /apk/back/                            #该模块代表的目标服务器中的目录,目标服务其中必须有此目录

#......可配置多个模块



【2】rsync认证账密配置



<1>配置虚拟用户及密码


在目标服务器B,C中配置

设置的虚拟账号和指定的密码文件位置必须与rsync配置文件中相应
可以设置多个,每行一个用户名和密码
格式 虚拟账号:密码


vim /etc/rsync.password 

rsyncback:back23%#¥..@#$


<2>调整权限

chmod 600 /etc/rsync.password


<3>配置虚拟用户密码


在源服务器A中配置密码文件(此处的密码文件需与后面的sersync中的配置相应)


内容仅配置密码即可

vim /etc/rsync.password

back23%#¥..@#$


【3】rsync防火墙及安全组配置



<1>如果都使用的是云服务器,通常需要进入目标服务器B、C的安全组,入口放开配置的rsync端口(默认873);源服务器A的出口通常不用配置



<2>如果使用的是iptables或firewalld防火墙,需要放开rsync端口

关闭selinux

vim /etc/selinux/config 
SELINUX=disabled

setenforce 0

开放873端口

iptables:
vim /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT

/etc/init.d/iptables restart 


firewalld:

firewall-cmd --zone=public --permanent --add-port=873/tcp
firewall-cmd --reload


<3>如果还有其他防火墙注意放开端口



<4>启动目标服务器的rsync

systemctl start rsyncd
systemctl enable rsyncd




【4】rsync传输测试



<1>进入源服务器中执行

格式:
rsync 参数  源服务器中要传输的数据  虚拟用户名@目标服务器IP::模块名/ --password-file=源服务器中的密码文件

rsync -avzP /back/test1/ rsyncback@192.168.10.2::back1/ --password-file=/etc/rsync.password
rsync -avzP /back/test1/ rsyncback@192.168.10.3::back1/ --password-file=/etc/rsync.password

如有报错,请查看
端口是否打开
虚拟用户名或指定的密码文件是否有错误
源服务器和目标服务器是否有对应的目录,是否有权限
源服务器和目标服务器的账密文件是否正确,是否有权限

查看目标服务器中back1模块代表的/root/jiema/中,是否有源服务器中/back/test1下的文件。如接收成功即为完成。



【5】Sersync安装


进入源服务器中执行



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

ls /proc/sys/fs/inotify

max_queued_events  max_user_instances  max_user_watches

出现以上的文件,说明服务器内核支持inotify



<2>修改inotify默认参数(如果参数小,再修改)

修改上面3个配置文件的参数

```bash
sysctl -wfs.inotify.max_queued_events="99999999"
sysctl -w fs.inotify.max_user_watches="99999999"
sysctl -wfs.inotify.max_user_instances="65535"
 
vim /etc/sysctl.conf 
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535
sysctl-p
max_queued_events   inotify队列最大长度,如果值太小,会出现”EventQueueOverflow“错误,导致监控文件不准确
max_user_watches    max_user_watches值需要大于要同步文件及目录数量
max_user_instances  每个用户创建inotify实例最大值


<3>sersync安装

可从官网下载:
https://code.google.com/archive/p/sersync/downloads

or

wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sersync/sersync2.5.4_64bit_binary_stable_final.tar.gz

or

其他来源下载


【6】sersync配置



<1>解压

tar  -zxvf  sersync2.5.4_64bit_binary_stable_final.tar.gz  -C   /usr/local/
mv /usr/local/GNU-Linux-x86  /usr/local/sersync


<2>创建目录(便于管理)

mkdir /usr/local/sersync/conf
mkdir /usr/local/sersync/bin
mkdir /usr/local/sersync/log

cd /usr/local/sersync/
mv confxml.xml   conf/
mv sersync2  bin/


<3>配置环境变量

echo "export PATH=$PATH:/usr/local/sersync/bin" >> /etc/profile
source /etc/profile

cd conf/
cp confxml.xml back1_confxml.xml


<4>配置sersync配置文件

其配置文件的使用方式类似于resin和tomcat。使用时,要指定配置文件。
每配置一个源目录,创建一个配置文件(仅修改添加了注释部分的内容即可)。

true为打开配置;false为禁用配置


cat /usr/local/sersync/conf/back1_confxml.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>
    <debug start="false"/>
    <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="true"/>
	<closeWrite start="true"/>
	<moveFrom start="true"/>
	<moveTo start="true"/>
	<attrib start="true"/>
	<modify start="true"/>
    </inotify>

    <sersync>
	<localpath watch="/script/">                                 
	<!-- watch 本地要同步到目标服务器的目录 -->
	    <!--remote ip 目标服务器IP;name 要推送到目标服务器的那个模块上,填写模块名;可配置多条-->
	    <remote ip="192.168.10.2" name="back1"/>                 
	    <remote ip="192.168.10.3" name="back1"/>
	    <!--<remote ip="192.168.8.39" name="tongbu"/>-->
	    <!--<remote ip="192.168.8.40" name="tongbu"/>-->
	</localpath>
	<rsync>
	    <commonParams params="-aruz"/>                           
	    <!--params为rsync使用的参数>
	    <auth start="true" users="rsyncback" passwordfile="/etc/rsync.password"/>    
	    <!--true开启认证,users为配置的虚拟账号,passwordfile为该虚拟账号-->
	    <userDefinedPort start="false" port="874"/><!-- port=874 -->
	    <timeout start="true" time="100"/><!-- timeout=100 -->  
	    <!--time为设置超时时间 -->
	    <ssh start="false"/>
	</rsync>
	<failLog path="/usr/local/sersync/logs/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->                                                  
	<!--failLog path为指定失败日志位置  timeToExecute为指定时间进行同步失败文件重新同步,单位分钟,该配置为60分钟 -->
	<crontab start="false" schedule="600"><!--600mins-->
	<!-- schedule为配置全目录同步,单位分钟,该配置为600分钟,如需开启使用true-->       
	    <crontabfilter start="false">
		<exclude expression="*.php"></exclude>
		<exclude expression="info/*"></exclude>
	    </crontabfilter>
	</crontab>
	<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>


【6】Sersync+rsync数据同步



<1>启动

sersync2 -d -r -o /usr/local/sersync/back1_confxml.xml
sersync2 -d -r -o /usr/local/sersync/back2_confxml.xml


<2>在源服务器的源目录中创建,删除,修改,查看目标服务器对应的模块的目录中是否产生同样的变动

第一次传输,如果文件较大,就先rsync传输一下
由于使用的rsync传输,虽然看到了文件名,但是实际上还是处于持续写入的状态



<3>配置开机启动

vim /etc/rc.local

/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/back1_confxml.xml
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/back2_confxml.xml


【7】Sersync+rsync数据双向同步


上面已经完成了数据的单向同步。即源服务器的源目录变动后,同步到目标服务器的目标目录。

关于数据的双向同步,即一个目录,无论是源服务器或目标服务器对它的改动,会在双方进行同步。实际上只需要将源服务器做为目标服务器,目标服务器做为源服务器,再按照上面的流程做一遍即可。但是要区分好虚拟账号及密码的存储文件。这里就不演示了。