rsync+inotify和sersync实现实时同步
一、前言
最近有一个项目需要进行图片文件同步,图片数量有五百多万张,之前使用rsync进行同步数据,每分钟执行一次同步,每次都需要扫描所有文件进行对比,才进行差量传输扫描文件,刚开始没有什么问题,当图片数量增多后对比文件将非常耗时,每次同步要花好几分钟,有时会导致用户上传图片几分钟后才能查看,所以准备对同步进行优化使用 rsync+inotify 或 rsync+sersync 来实现实时同步
二、Rsync+Inotify-tools
Rsync+Inotify-tools
1):Inotify-tools只能记录下被监听的目录发生了变化(包括增加、删除、修改),并没有把具体是哪个文件或者哪个目录发生了变化记录下来; 2):rsync在同步的时候,并不知道具体是哪个文件或者哪个目录发生了变化,每次都是对整个目录进行同步,当数据量很大时,整个目录同步非常耗时(rsync要对整个目录遍历查找对比文件),因此,效率很低。
rsync安装配置请点击 linux 安装并配置rsync
1.安装inotify-tools
inotify-tools下载地址:http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz 上传inotify-tools-3.14.tar.gz到/usr/local/src目录下 [root@localhost ~]# cd /usr/local/src [root@localhost ~]# tar zxvf inotify-tools-3.14.tar.gz #解压 [root@localhost ~]# cd inotify-tools-3.14 #进入解压目录 [root@localhost ~]# ./configure #配置 [root@localhost ~]# make && make install #编译安装
inotify参数
-m 是保持一直监听 -r 是递归查看目录 -q 是打印出事件 -e create,move,delete,modify,attrib 是指 “监听 创建 移动 删除 写入 权限” 事件
2.修改inotify默认参数(inotify默认内核参数值太小)
查看系统默认参数值 [root@localhost ~]# sysctl -a | grep max_queued_events 结果是:fs.inotify.max_queued_events = 16384 [root@localhost ~]# sysctl -a | grep max_user_watches 结果是:fs.inotify.max_user_watches = 8192 [root@localhost ~]# sysctl -a | grep max_user_instances 结果是:fs.inotify.max_user_instances = 128 修改参数: [root@localhost ~]# sysctl -w fs.inotify.max_queued_events="99999999" [root@localhost ~]# sysctl -w fs.inotify.max_user_watches="99999999" [root@localhost ~]# sysctl -w fs.inotify.max_user_instances="65535" [root@localhost ~]# vim /etc/sysctl.conf #添加以下代码 fs.inotify.max_queued_events=99999999 fs.inotify.max_user_watches=99999999 fs.inotify.max_user_instances=65535 #保存退出 参数说明: fs.inotify.max_queued_events:表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。 fs.inotify.max_user_instances:表示每一个real user ID可创建的inotify instatnces的数量上限,默认128. fs.inotify.max_user_watches:表示同一用户同时可以添加的watch数目(watch一般是针对目录,决定了同时同一用户可以监控的目录数量)
3.创建脚本,实时触发rsync进行同步
脚本内容:
#!/bin/bash #!/bin/sh #源服务器目录 srcdir=/root/test/ #目标服务器模块名 dstdir=test #不需要同步的目录,如果有多个,每一行写一个目录,使用相对于同步模块的路径; #excludedir=/usr/local/inotify/exclude.list #user rsyncuser=rsync #认证文件 rsyncpassdir=/etc/rsyncd/rsync.pass #/usr/local/bin/inotifywait inot='/usr/local/bin/inotifywait' dstip="192.168.2.204" for ip in $dstip do rsync -avzPH --port=873 --progress --delete --exclude-from=$excludedir $srcdir $rsyncuser@$ip::$dstdir --password-file=$rsyncpassdir done $inot -mrq --timefmt '{5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}d/{5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}m/{5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}y {5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}H:{5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}M' --format '{5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}T {5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}w{5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}f{5749fe182deba6f703e69800a8cc3afb9894ad400f350437bd2be724fa41f418}e' -e close_write,modify,delete,create,attrib,move $srcdir | while read file do for ip in $dstip do rsync -avzPH --port=873 --progress --delete --exclude-from=$excludedir $srcdir $rsyncuser@$ip::$dstdir --password-file=$rsyncpassdir echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1 done done
脚本参数说明:
srcdir=/root/test #源服务器同步目录 dstdir=test #目标服务器rsync同步目录模块名称 excludedir=/usr/local/bin/inotifywait #不需要同步的目录,如果有多个,每一行写一个目录,使用相对于同步模块的路径 #例如:不需要同步/home/www.osyunwei.com/目录下的a目录和b目录下面的b1目录,exclude.list文件可以这样写 a/ b/b1/ rsyncuser=rsync #目标服务器rsync同步用户名 rsyncpassdir=/etc/rsyncd/rsync.pass #目标服务器rsync同步用户的密码在源服务器的存放路径 dstip="192.168.2.204" #目标服务器ip,多个ip用空格分开 /tmp/rsync.log #脚本运行日志记录
三、Rsync+sersync
Rsync+sersync
1):sersync是基于Inotify开发的,类似于Inotify-tools的工具 2):sersync可以记录下被监听目录中发生变化的(包括增加、删除、修改)具体某一个文件或某一个目录的名字; 3):rsync在同步的时候,只同步发生变化的这个文件或者这个目录(每次发生变化的数据相对整个同步目录数据来说是很小的,rsync在遍历查找比对文件时,速度很快),因此,效率很高。 小结:当同步的目录数据量不大时,建议使用Rsync+Inotify-tools;当数据量很大(几百G甚至1T以上)、文件很多时,建议使用Rsync+sersync。
1.软件安装
rsync安装配置请点击 linux 安装并配置rsync
上传sersync2.5.4_64bit_binary_stable_final.tar.gz到/usr/local/src目录下
[root@localhost ~]# cd /usr/local/src [root@localhost ~]# tar zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz #解压 [root@localhost ~]# mv GNU-Linux-x86 /usr/local/sersync #移动目录到/usr/local/sersync
2.配置sersync
[root@localhost ~]# cd /usr/local/sersync #进入sersync安装目录
[root@localhost ~]# cp confxml.xml confxml.xml-bak #备份原文件
[root@localhost ~]# vim confxml.xml #编辑,修改下面的代码
3.xml配置文件说明:
#############################说明: xml配置文件的注释不用“#”,而是################ #服务器同步目录 #目标服务器IP地址.目标服务器rsync同步目录模块名称 #目标服务器rsync同步用户名,#目标服务器rsync同步用户的密码在源服务器的存放路径 #脚本运行失败日志记录 failLog path="/tmp/rsync_fail_log.sh" #设置为true,每隔600分钟执行一次全盘同步 #hostip与port是针对插件的保留字段,对于同步功能没有任何作用,保留默认即可; #Debug开启开关,设置为true,表示开启debug模式,会在sersync正在运行的控制台打印inotify时间与rsync同步命令; #XFS文件系统开关,对于xfs文件系统的用户,需要将这个选项开启,才能使用sersync正常工作; #filter文件过滤功能,说明:一般情况下,不给客户端添加过滤,如有必要才添加;对于大多数应用,可以尝试把createFile(监控文件事件选项)设置为false来提高性能,减少rsync通讯;因为拷贝文件到监控目录会产生create事件与close_write事件,所以如果关闭create事件,只监控文件拷贝结束时的时间close_write,同样可以实现文件完整同步;
注意:强将createFolder保持为true,如果将createFolder设为false,则不会对产生的目录进行监控,该目录下的子文件与子目录也不会被监控;所以除非特殊需要,请开启; 默认情况下对创建文件(目录)事件与删除文件(目录)事件都进行监控,如果项目中不需要删除远程目标服务器的文件(目录),则可以将delete参数设置为false,则不对删除事件进行监控;
4.启动及参数:
[root@localhost ~]# /usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/confxml.xml ./sersync -r -r参数作用是:开启实时监控的之前对主服务器目录与远程目标机器的目录进行一次整体同步;如果需要将sersync运行前,主服务器目录下已经存在的所有文件或目录全部同步到远端,则要以 -r参数运行sersync,将本地与远程整体同步一次; 提别说明:如果设置了过滤器,即在xml文件中,filter为true,则暂时不能使用-r参数进行整体同步; ./sersync -o xx.xml 不指定 -o参数: sersync使用sersync可执行文件目录下的默认配置文件confxml.xml 指定 -o 参数:可以指定多个不同的配置文件,从而实现sersync多进程多实例的数据同步 ./sersync -n num -n参数为:指定默认的线程池的线程总数; 例如: ./sersync -n 5 则指定线程总数为5,如果不指定,默认启动线程池数量是10,如果cpu使用过高,可以通过该参数调低,如果机器配置较高,可以调高默认的线程总数,提升同步效率; ./sersync -d -d参数为:后台服务,通常情况下使用 -r参数对本地到远端整体同步一遍后,在后台运行此参数启动守护进程实时同步;在第一次整体同步时,-d 和 -r参数经常会联合使用; ./sersync -m pluginName -m参数:不进行同步,只运行插件 ./sersync -m pluginName 例如:./sersync -m command,则在监控到事件后,不对远程目标服务器进行同步,而是直接运行command插件 组合命令使用说明: -n 8 -o liubl.xml -r -d 多个参数可以配合使用,例如:./sersync -n 16 -o config.xml -r -d 表示设置线程池工作线程为16个,指定liubl.xml作为配置文件,在实时监控前 做一次整体同步,以守护进程方式在后台运行; ./sersync --help 很遗憾,它没有查看帮助(需要的话2条路,要么看源代码,要么自测求验证)
5.添加sersync检查脚本,添加定时,每小时检查一次
[root@localhost ~]# vim /home/crontab/check_sersync.sh #编辑,添加以下代码
#!/bin/sh sersync="/usr/local/sersync/sersync2" confxml="/usr/local/sersync/confxml.xml" status=$(ps aux |grep 'sersync2'|grep -v 'grep'|wc -l) if [ $status -eq 0 ]; then $sersync -d -r -o $confxml & else exit 0; fi
四、测试sersync实时触发rsync同步脚本是否正常运行