对于数据的实时同步,例如:某些配置文件或web文件在集群中的同步,通常我们有几种方式:
使用网络raid(例如:nfs/drbd)将某些目录由源服务器挂载到目标服务器(由于网络raid严重依赖网络,尤其是处于不同的网络环境,当网络联通失败后,客户端挂载的网络磁盘会丢失,必须重新挂载。优点是可以将有大量文件的目录直接挂载过去,虚拟磁盘不占用目标服务器的空间。常用于同一内网环境下)
使用rsync/scp及其他的方式将源文件传输到对应的目标服务器的目录(需要将源文件进行传输,传输过程依赖网速,如果是大文件或大量小文件的传输,速度缓慢,占用目标服务器空间。常用方法:rsync+inotify-tools / rsync+sersync)
下面介绍的是 rsync+sersync实现数据的实时同步/传输。
Inotify-tools与sersync都是基于Inotify开发的用于辅助rsync传输的工具。
Inotify-tools仅记录下被监听的目录发生的变化,并没有把发生了变化的具体的文件或者目录记录下来,当它监听到目录变化时,会产生一个rsync进程(单线程),遍历后,开始同步整个目录,当目录数据量或小文件数较大时,同步耗时。配置较sersync复杂,还得添加脚本。
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的基础操作:
https://blog.csdn.net/GX_1_11_real/article/details/80395588
在目标服务器中执行
<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/ #该模块代表的目标服务器中的目录,目标服务其中必须有此目录
#......可配置多个模块
<1>配置虚拟用户及密码
在目标服务器B,C中配置
设置的虚拟账号和指定的密码文件位置必须与rsync配置文件中相应
可以设置多个,每行一个用户名和密码
格式 虚拟账号:密码
vim /etc/rsync.password
rsyncback:back23%#¥..@#$
<2>调整权限
chmod 600 /etc/rsync.password
<3>配置虚拟用户密码
在源服务器A中配置密码文件(此处的密码文件需与后面的sersync中的配置相应)
内容仅配置密码即可
vim /etc/rsync.password
back23%#¥..@#$
<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
<1>进入源服务器中执行
格式:
rsync 参数 源服务器中要传输的数据 虚拟用户名@目标服务器IP::模块名/ --password-file=源服务器中的密码文件
rsync -avzP /back/test1/ [email protected]::back1/ --password-file=/etc/rsync.password
rsync -avzP /back/test1/ [email protected]::back1/ --password-file=/etc/rsync.password
如有报错,请查看
端口是否打开
虚拟用户名或指定的密码文件是否有错误
源服务器和目标服务器是否有对应的目录,是否有权限
源服务器和目标服务器的账密文件是否正确,是否有权限
查看目标服务器中back1模块代表的/root/jiema/中,是否有源服务器中/back/test1下的文件。如接收成功即为完成。
进入源服务器中执行
<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
其他来源下载
<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>
<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
上面已经完成了数据的单向同步。即源服务器的源目录变动后,同步到目标服务器的目标目录。
关于数据的双向同步,即一个目录,无论是源服务器或目标服务器对它的改动,会在双方进行同步。实际上只需要将源服务器做为目标服务器,目标服务器做为源服务器,再按照上面的流程做一遍即可。但是要区分好虚拟账号及密码的存储文件。这里就不演示了。