序言:如果我们后端有多台网站服务器或者文件服务器,而且没有好 的文件同步机制,那么当我们升级程序或者更新文件的时候,就需要每台服务器或者目录都要更新,这样很容易出问题,并很容易导致两边的文件不一致,从而出现 很多莫民其妙的问题。因此我们需要使用好的文件同步方式来实现几个后端服务器文件的同步,目前广泛采用的方案是使用rsync+inotify的方式来实现文件的触发更新。原理是采用inotify来对文件进行监控,当监控到文件有文件发生改变的时候,就会调用rsync实现触发式实时同步!本文就来详细介绍金山的一个居于inotify+rsync进行二次开发实现文件同步的小工具sersync,能够很方便的实现文件触发式同步
1、 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)
备注:上面的文件也包括目录。
2、 Rsync简介
rsync,remote synchronize顾名思意就知道它是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限、时间、软硬链接等附加信息。rsync是用 “rsync 算法”提供了一个客户机和远程文件服务器的文件同步的快速方法,而且可以通过ssh方式来传输文件,这样其保密性也非常好,另外它还是免费的软件。
rsync 包括如下的一些特性:
Ø 能更新整个目录和树和文件系统;
Ø 有选择性的保持符号链链、硬链接、文件属于、权限、设备以及时间等;
Ø 对于安装来说,无任何特殊权限要求;
Ø 对于多个文件来说,内部流水线减少文件等待的延时;
Ø 能用rsh、ssh 或直接端口做为传输入端口;
Ø 支持匿名rsync 同步文件,是理想的镜像工具;
3、 sersync简介
sersync利用inotify与rsync对服务器进行实时同步,其中inotify用于监控文件系统事件,rsync是目前广泛使用的同步算法,其优点是只对文件不同的部分进行操作,所以其优势大大超过使用挂接文件系统的方式进行镜像同步。由金山的周洋开发完成,是目前使用较多的文件同步工具之一。该工具和其他的工具相比有如下优点:
Ø sersync是使用c++编写,由于只同步发生更改的文件,因此比其他同步工具更节约时间、带宽;
Ø 安装方便、配置简单;
Ø 使用多线程进行同步,能够保证多个服务器实时保持同步状态;
Ø 自带出错处理机制,通过失败队列对出错的文件重新出错,如果仍旧失败,则每10个小时对同步失败的文件重新同步;
Ø 自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次;
Ø 自带socket与http协议扩展,你可以方便的进行二次开发;
项目地址:http://code.google.com/p/sersync/
我们常用到的是rsync+inotify来对服务器进行实时同步,其中inotify用于监控文件系统事件,rsync是目前广泛使用的同步算法,其优点是只对文件不同的部分进行操作,所以其优势大大超过使用挂接文件系统的方式进行镜像同步。
目 前使用的比较多的同步程序版本是inotify-tools,另外一个是google开源项目Openduckbill(依赖于inotify- tools),这两个都是基于脚本语言编写的,其设计思路同样是采用inotify与rsync命令。 相比较上面两个项目,本项目优点是:
sersync是使用c++编写,而且对linux系统文件系统产生的临时文件和重复的文件操作进行过滤(详细见附录,这个过滤脚本程序没有实现),所以在结合rsync同步的时候,节省了运行时耗和网络资源。因此更快。
相比较上面两个项目,sersync配置起来很简单,其中bin目录下已经有基本上静态编译的2进制文件,配合bin目录下的xml配置文件直接使用即可。
另外本项目相比较其他脚本开源项目,使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态。
本项目有出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则按设定时长对同步失败的文件重新同步。
本项目自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次。无需再额外配置crontab功能。
如上图所示,线程组线程是等待线程队列的守护线程,当队列中有数据的时候,线程组守护线程逐个唤醒,当队列中inotify事件较多的时候就会被全部唤醒一起工作。这样设计的目的是能够同时处理多个inotify事件,重发利用服务器的并发能力(核数*2+2)。
之所以称之为线程组线程,是因为每个线程在工作的时候,会根据服务器的数量建立子线程,子线程可以保证所有的文件与各个服务器同时同步,当要同步的文件较大的时候,这样设计可以保证各个远程服务器可以同时获得要同步的文件。
服 务线程的作用有三个,首先是处理同步失败的文件,将这些文件再次同步,对于再次同步失败的文件会生成rsync_fail_log.sh脚本,记录失败的 事件。同时每隔10个小时执行脚本一次,同时清空脚本。服务线程的第三个作用是crontab功能,可以每隔一定时间,将所有路径整体同步一次。
由此图总结可见:
Sersync还具有一下机制:
双向同步过程中,如果同事修改一个文件,则以时间为准
在在
三、Sersync安装和配置具体步骤
1.1.1.1 server
1.1.1.2 client
1 、Server端安装
- #wget http://sersync.googlecode.com/files/sersync2.5_32bit_binary_stable_final.tar.gz
- # tar xf sersync2.5_32bit_binary_stable_final.tar.gz
- # cd GNU-Linux-x86/
通过以上简单三步,即可完成其安装!解压后里面就两个文件,一个sersync2和一个confxml.xml,其中第一个是一个二进制文件,也即是开户服务的文件,后面的是配置文件!
下面对配置文件进行解释
- <?xml version="1.0" encoding="ISO-8859-1"?>
- <head version="2.5">
- <host hostip="localhost" port="8008"></host> #针对插件保留的,默认配置即可
- <debug start="false"/> #开户debug信息,会在sersync当前运行台,打印Debug信息
- <fileSystem xfs="false"/> #是否支持xfs文件系统
- <filter start="false"> # 是否开户文件过滤,可以在下面添加过滤类型
- <exclude expression="(.*)\.svn"></exclude>
- <exclude expression="(.*)\.gz"></exclude>
- <exclude expression="^info/*"></exclude>
- <exclude expression="^static/*"></exclude>
- </filter>
- <inotify> # inotify监控的事件
- <delete start="false"/> #是否保持Sersync和同步端两端文件完全一致
- <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/mp3/"> #这里定义要监控的本地目录,这个很重要
- <remote ip="1.1.1.100" name="mp3"/> #要同步到哪台服务器,Rsync标签是什么
- <!--<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="syncuser" passwordfile="/etc/rsyncd/rsyncd.pass"/>
- <userDefinedPort start="false" port="874"/><!-- port=874 --> # 定义rsync端口
- <timeout start="false" time="100"/><!-- timeout=100 --> #定义传输超时时间
- <ssh start="false"/> #Rsync的时候,是否使用ssh加密
- </rsync>
- <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
- <crontab start="false" schedule="600"><!--600mins--> #定义crontab定期完全同步两端文件
- <crontabfilter start="false"> #crontab同步时候的过滤条件,上面的过滤部开头要开
- <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>
因为这里rsync的时候,使用了认证用户和密码,所以要定义一下密码文件
注:此无需用户名
- # vim /etc/rsyncd/rsyncd.pass
- 123456
然后权限改为600
- # chmod 600 /etc/rsyncd/rsyncd.pass
上面对配置文件进行了简单的说明,下面详细的说一下!
- <host hostip="localhost" port="8008"></host>
hostip与port是针对插件的保留字段,对于同步功能没有任何作用,保留默认即可。
- <filter start="true">
- <exclude expression="(.*)\.gz"></exclude>
- <exclude expression="^info/*"></exclude>
- </filter>
将start设置为 true,在exclude标签中,填写正则表达式,默认给出两个例子分别是过滤以”.gz”结尾的文件与过滤监控目录下的info路径(监控路径 /info /*),可以根据需要添加,但开启的时候,自己测试一下,正则表达式如果出现错误,控制台会有提示。相比较使用rsync 的exclude功能,被过滤的路径,不会加入监控,大大减少rsync的通讯量。
- <inotify>
- <delete start="true"/>
- <createFolder start="true"/>
- <createFile start="true"/>
- </inotify>
对于大多数应用,可以尝试把createFile(监控文件事件选项)设置为false来提高性能,减少 rsync通讯。因为拷贝文件到监控目录会产生create事件与close_write事件,所以如果关闭create事件,只监控文件拷贝结束时的事 件close_write,同样可以实现文件完整同步。
注意:强将createFolder保持为true,如果将createFolder设为false,则不会对产生的目录进行监控,该目录下的子文 件与子目录也不会被监控。所以除非特殊需要,请开启。默认情况下对创建文件(目录)事件与删除文件(目录)事件都进行监控,如果项目中不需要删除远程目标 服务器的文件(目录),则可以将delete 参数设置为false,则不对删除事件进行监控。
- <debug start="false"/>
设置为true,开启debug模式,会在sersync正在运行的控制台,打印inotify事件与rsync同步命令。
- <fileSystem xfs="false"/>
对于xfs文件系统的用户,需要将这个选项开启,才能使sersync正常工作.
- <localpath watch="/opt/tongbu">
- <remote ip="192.168.0.104" name="tongbu1"/>
- <!--<remote ip="192.168.8.39" name="tongbu"/>-->
- <!--<remote ip="192.168.8.40" name="tongbu"/>-->
- </localpath>
文件监控与远程同步设置,这里使用watch设定本地要监控的目录,使用remote设置远端的服务器IP,使用name设置无端rsync服务里面定义的标签
- <rsync>
- <commonParams params="-artuz"/>
- <auth start="false" users="root" passwordfile="/etc/rsync.pas"/>
- <userDefinedPort start="false" port="874"/><!-- port=874 -->
- <timeout start="false" time="100"/><!-- timeout=100 -->
- <ssh start="false"/>
- </rsync>
commonParams可以用户自定义rsync参数,默认是-artuz
auth start=”false” 设置为true的时候,使用rsync的认证模式传送,需要配置user与passwrodfile(–password-file=/etc /rsync.pas),来使用。userDefinedPort 当远程同步目标服务器的rsync端口不是默认端口的时候使用(–port=874)。timeout设置rsync的timeout时间 (–timeout=100)。ssh 使用rsync -e ssh的方式进行传输。
- <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/>
对于失败的传输,会进行重新传送,再次失败就会写入rsync_fail_log,然后每隔一段时间(timeToExecute进行设置)执行该脚本再次重新传送,然后清空该脚本。可以通过path来设置日志路径。
- <crontab start="false" schedule="600"><!--600mins-->
- <crontabfilter start="false">
- <exclude expression="*.gz"></exclude>
- <exclude expression="info/*"></exclude>
- </crontabfilter>
- </crontab>
crontab可以对监控路径与远程目标主机每隔一段时间进行一次整体同步,可能由于一些原因两次失败重传都失败了,这个时候如果开启了 crontab功 能,还可以进一步保证各个服务器文件一致,如果文件量比较大,crontab的时间间隔要设的大一些,否则可能增加通讯开销。schedule这个参数是 设置crontab的时间间隔,默认是600分钟
如果开启了filter文件过滤功能,那么crontab整体同步也需要设置过滤,否则虽然实时同步的时候文件被过滤了,但crontab整体同步 的时候 如果不单独设置crontabfilter,还会将需过滤的文件同步到远程,crontab的过滤正则与filter过滤的不同,也给出了两个实例分别对 应与过滤文件与目录。总之如果同时开启了filter与crontab,则要开启crontab的crontabfilter,并按示例设置使其与 filter的过滤一一对应。
2、client配置Rsync服务
首先安装rsync
- # sudo apt-get install rsync
然后定义rsync的配置文件
- # Section 1: Global settings
- port = 873
- uid = root
- gid = root
- use chroot = yes
- read only = no
- max connections = 7
- pid file = /var/run/rsyncd.pid
- log file = /var/log/rsyncd.log
- hosts allow = *
- transfer logging = yes
- log format = %t %a %m %f %b
- syslog facility = local3
- timeout = 300
- # Section 2: Directory to be synced
- [mp3]
- path = /data/
- list = yes
- ignore errors = yes
- auth users = syncuser
- secrets file = /etc/rsyncd/rsync.pass
定义一下密码文件----注:此需用户名:密码
- # vim /etc/rsyncd/rsync.pass
- syncuser:123456
然后就可以开户服务了
- [root@node100 ~]# rsync --daemon --config=/etc/rsync.conf
- [root@node100 ~]# ps -ef | grep rsync
- root 3124 1 0 17:26 ? 00:00:00 rsync --daemon --config=/etc/rsync.conf
- root 3130 3085 0 17:26 pts/0 00:00:00 grep rsync
如果需要将sersync运行前,已经存在的所有文件或目录全部同步到远程,要以-r参数运行sersync,将本地与远程整体同步一次。
如果设置了过滤器,即在xml文件中,filter为true,则暂时不能使用-r参数进行整体同步。-r参数将会无效。
- ./sersync2 -r
开户服务使用以下命令
- ./sersync2 -d
对于sersync使用可执行文件目录下的默认配置文件confxml.xml,如果需要使用另一个配置文件,可以使用-o参数指定其它配置文件。
- ./sersync2 -o XXXX.xml
指定默认的线程池的线程总数
- ./sersync2 -n num
转自 http://gm100861.blog.51cto.com/1930562/949094