序言:如果我们后端有多台网站服务器或者文件服务器,而且没有好的文件同步机制,那么当我们升级程序或者更新文件的时候,就需要每台服务器或者目录都要更新,这样很容易出问题,并很容易导致两边的文件不一致,从而出现很多莫民其妙的问题。因此我们需要使用好的文件同步方式来实现几个后端服务器文件的同步,目前广泛采用的方案是使用rsync+inotify的方式来实现文件的触发更新。原理是采用inotify来对文件进行监控,当监控到文件有文件发生改变的时候,就会调用rsync实现触发式实时同步!本文就来详细介绍金山的一个居于inotify+rsync进行二次开发实现文件同步的小工具sersync,能够很方便的实现文件触发式同步
inotify简介
Inotify 是基于inode级别的文件系统监控技术,是一种强大的、细粒度的、异步的机制,它满足各种各样的文件监控需要,不仅限于安全和性能,内核要求2.6.13以上,inotify能监控非常多的文件系统事件,通过监控这些事件来监控文件是否发生变更,然后通过rsync来更新发生变更的文件,Inotify 可以监视的文件系统事件包括:
・IN_ACCESS,即文件被访问
・IN_MODIFY,文件被 write
・IN_ATTRIB,文件属性被修改,如 chmod、chown、touch 等
・IN_CLOSE_WRITE,可写文件被 close
・IN_CLOSE_NOWRITE,不可写文件被 close
・IN_OPEN,文件被 open
・IN_MOVED_FROM,文件被移走,如 mv
・IN_MOVED_TO,文件被移来,如 mv、cp
・IN_CREATE,创建新文件
・IN_DELETE,文件被删除,如 rm
・IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
・IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己
・IN_UNMOUNT,宿主文件系统被 umount
・IN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
・IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)
备注:上面的文件也包括目录。
Rsync简介
rsync,remote synchronize顾名思意就知道它是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限、时间、软硬链接等附加信息。rsync是用 “rsync 算法”提供了一个客户机和远程文件服务器的文件同步的快速方法,而且可以通过ssh方式来传输文件,这样其保密性也非常好,另外它还是免费的软件。
rsync 包括如下的一些特性:
能更新整个目录和树和文件系统;
有选择性的保持符号链链、硬链接、文件属于、权限、设备以及时间等;
对于安装来说,无任何特殊权限要求;
对于多个文件来说,内部流水线减少文件等待的延时;
能用rsh、ssh 或直接端口做为传输入端口;
支持匿名rsync 同步文件,是理想的镜像工具;
sersync简介
sersync利用inotify与rsync对服务器进行实时同步,其中inotify用于监控文件系统事件,rsync是目前广泛使用的同步算法,其优点是只对文件不同的部分进行操作,所以其优势大大超过使用挂接文件系统的方式进行镜像同步。由金山的周洋开发完成,是目前使用较多的文件同步工具之一。该工具和其他的工具相比有如下优点:
sersync是使用c++编写,由于只同步发生更改的文件,因此比其他同步工具更节约时间、带宽;
安装方便、配置简单;
使用多线程进行同步,能够保证多个服务器实时保持同步状态;
自带出错处理机制,通过失败队列对出错的文件重新出错,如果仍旧失败,则每10个小时对同步失败的文件重新同步;
自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次;
自带socket与http协议扩展,你可以方便的进行二次开发;
sersync实现触发式文件同步实战
服务器文件同步图
2.从服务器的安装配置
a)安装rsync
yum -y install rsync
b)配置rsync
Rsync配置文件的配置
cat /etc/rsyncd.conf
# Rsync configuration file
uid = root
gid = root
port = 873
max connections = 20000
use chroot = yes
timeout = 200
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log format = %t %a %m %f %b
auth users = root
secrets file = /etc/rsyncd.secret
[test]
path = /data/test/
comment = "test directory file"
list = yes
read only = no
ignore errors = yes
hosts allow = 192.168.3.205
hosts deny = *
Rsync密码文件的配置
cat /etc/rsyncd.secret
root:abc123@#$
chmod 600 /etc/rsyncd.secret
需要设置密码文件为600权限,不然同步的时候会报password file must not be other-accessible错误!
c)Rsync的启动
Rsync的启动有两种方式,两种方式哪一种都可以,读者可以自行选择:
一种是采用daemon的方式启动:
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
另外一种是xinetd集成启动方式:
chkconfig xined on
chkconfig rsync on
/etc/init.d/xinetd start
d)验证rsync是否启动
查看进程和端口是否存在
[root@test_machine test]# ps aux | grep rsync
root32750.00.065516472 ?Ss13:440:00 /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
root33060.00.171812936 ?S14:490:00 /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
[root@test_machine test]# netstat -lnp | grep rsync
tcp00 0.0.0.0:8730.0.0.0:*LISTEN3275/rsync
tcp00 :::873:::*LISTEN3275/rsync
3.主服务器的安装配置
u安装rsync
yum -y install rsync
安装sersync
下载安装文件
wget http://sersync.googlecode.com/files/sersync2.5_64bit_binary_stable_final.tar.gz
解压并拷贝到安装目录
tar xzvf sersync2.5_64bit_binary_stable_final.tar.gz
mv GNU-Linux-x86 /usr/local/sersync
配置sersync
Sersync的配置
cat 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="false"/>
<closeWrite start="true"/>
<moveFrom start="true"/>
<moveTo start="true"/>
<attrib start="true"/>
<modify start="true"/>
</inotify>
<sersync>
<localpath watch="/data/test">
<!―-设置监控的目录-->
<remote ip="192.168.3.203" name="test"/>
<!―设置从服务器的IP-->
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
<commonParams params="-artuz"/>
<auth start="true" users="root" passwordfile="/etc/rsyncd.secret"/>
<!―-设置同步的用户名和密码文件-->
<userDefinedPort start="true" port="873"/><!-- port=874 -->
<!―-设置rsync的端口,要和从那边开启的端口一致-->
<timeout start="false" time="100"/><!--timeout=100 -->
<ssh start="false"/>
</rsync>
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
<crontab start="true" schedule="300"><!--600mins-->
<!―-设置300分钟全部同步一次-->
<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>
</head>
密码文件的配置
cat /etc/rsyncd.secret
abc123@#$
主服务器的密码配置文件不需要用户,如果添加用户的话同步的时候会报
rsync error: error starting client-server protocol (code 5) at main.c(1296) [sender=2.6.8]错误
启动sersync
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/confxml.xml
将上面的命令添加进/etc/rc.local,以后重启系统以后才能正常同步
脚本监控sersync
因为有的时候sersync脚本会自动关掉,因此需要写一个脚本自动的去检测该进程是否存在,不存在就启动,脚本内容如下:
cat /var/script/check_sersync.sh
#!/bin/bash
#Purpose: Check sersync whether it is alive
#Author: Carl Zhang
SERSYNC="/usr/local/sersync/sersync2"
CONF_FILE="/usr/local/sersync/confxml.xml"
STATUS=$(ps aux |grep 'sersync2'|grep -v 'grep'|wc -l)
if [ $STATUS -eq 0 ];
then
$SERSYNC -d -r -o $CONF_FILE &
else
exit 0;
fi
脚本写好以后,添加到计划任务中去
*/5 * * * * /var/script/check_sersync.sh > /dev/null 2>&1
总结:通过以上几步以后,你从服务器的/data/test就能够从主服务器实时更新,升级的时候只升级主服务器的文件,从服务器也会自动同步过去,减少你的工作量以及出错的概率