您的位置:首页 > 其它

inotify + rsync 打造文件实时同步

2013-07-21 22:20 225 查看
rsync 是Linux 下的一个文件同步利器,以高效的增量传输而闻名,适用于同步,备份等多个场合。几乎所有的Linux 发行版都收录了该软件,安装非常容易,以CentOS 6.4为例:

yum install rsync


rsync 有个特别之处,既可以作为服务端在后台运行,也可以作为客户端去连接服务器,甚至可以抛弃服务端,直接在本地文件系统上进行同步。

本文讲述 inotify+rsync 打造文件实时同步系统,先讲讲它与传统的rsync 服务器之间的区别,这点非常重要,很少有人提及这个,以至于新手在配置inotify+rsync 产生疑惑。

通常而言,rsync 作为服务端监听在873端口,等待客户端来连接,对应的模式是一个服务端,多个客户端,比如

rsync -avz --delete 10.1.1.11::web/ /var/www/
上面的例子中,只要规则允许,任何一个可以连接到10.1.1.11的机器,都可以去同步它。这种场合下,服务端10.1.1.11 是一般是权威内容的发布器,因此其内容是只读的。

在 inotify+rsync 场合中,工作模式是一个客户端,多个服务端,客户端掌握了权威内容,主动向服务端推送内容(服务端必须是可写的),例子如下:

rsync -avz --delete /var/www/ 10.1.1.11::web/
rsync -avz --delete /var/www/ 10.1.1.12::web/
rsync -avz --delete /var/www/ 10.1.1.13::web/
上面的例子就是,客户端将/var/www里的网页内容,主动推向3个服务端。

inotify 是个内核工具,能够监视文件目录的变化,客户端通过inotify 得知变化后立即主动将内容写入服务端。

所谓的原理就这么多了,关于inotify 的东西,别人都讲清楚了,不详述。

配置服务端
1 、创建并编辑文件 /etc/rsyncd.conf

uid = root
gid = root
address = 10.1.1.11
use chroot = no
read only = no
max connections = 512
log file = /var/log/rsyncd.log
log format = %t %a %m %f %b
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
[web]
path=/var/www/
list = yes
ignore errors = yes
hosts allow = 10.1.1.20
hosts deny = *


2、启动rsync 服务端

rsync --daemon -4
将上面一句命令加入/etc/rc.local ,可以让rsync 随系统启动。

3、配置防火墙,开启873端口

/sbin/iptables -A INPUT -s 10.1.1.20 -p tcp --dport 873 -j ACCEPT


4、服务端配置完成,如果有多个服务端,请依葫芦画瓢。

配置客户端
1、安装rsync

yum install rsync


2、安装inotify-tools

yum install inotify-tools --enablerepo=epel


3、写个脚本,一旦 inotify 发现变化,立即触发rsync 将变化推送到服务端。
#!/usr/bin/env bash
set -e
src=/var/www/
web01=10.1.1.11
web02=10.1.1.12
web03=10.1.1.13
/usr/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' \
-e modify,delete,create,attrib $src \
| while read files
do
/usr/bin/rsync -vzrtopg --delete --progress $src $web01::web/
/usr/bin/rsync -vzrtopg --delete --progress $src $web02::web/
/usr/bin/rsync -vzrtopg --delete --progress $src $web03::web/
echo $files have been pushed to all web servers.
done
4、启动脚本,并在后台运行,或者让它开机启动

chmod 755 /opt/inotify-rsync.sh
/opt/inotify-rsync.sh&
echo "/opt/inotify-rsync.sh&" >>/etc/rc.local


update 2014-04-18
上面的脚本可控性比较差,于是重新写了一个init脚本 。

/etc/init.d/realsync,权限755,支持chkconfig开机启动。

#!/bin/sh
#
# realsync - realtime sync with remote directory.
#
# chkconfig:  - 85 15
# description: realsync is a shell script which join "rsync" and "inotifywait" together \
#              to make realtime sync with remote directory.
### BEGIN INIT INFO
# Provides: realsync
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop:  0 1 6
# Short-Description: realtime sync with remote directory
### END INIT INFO
# Source function library.
. /etc/rc.d/init.d/functions
exec="/usr/bin/inotifywait"
prog=$(basename $exec)
lockfile=/dev/shm/$prog
opts="-mrqsd -e close_write,modify,create,attrib -o $lockfile"
#local directory to monitor
local_dir="/var/www"
#remote directory to rsync
remote_dir="10.1.1.11::web"
start() {
echo -n $"Starting $prog: "
touch $lockfile
daemon $exec $opts $local_dir
while [[ -s $lockfile ]];do
rsync -aqu $local_dir/ $remote_dir/
> $lockfile
done
retval=$?
echo
[ $retval -eq 0 ]
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
case "$1" in
start|stop|restart)
$1
;;
status)
status $prog
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 2
esac
开机启动

chkconfig realsync on


至此,inotify + rsync 全部搞定。

update 2016-01-11
为了让脚本看起来更像一个程序,写个稍稍“另类”一点的脚本。
1、inotifywait只监控一次event便退出,接着执行rsync命令
2、如果5分钟(300秒)内没有监控到event,inotifywait会超时退出,强制执行后面的rsync命令
3、写日志,睡眠1秒,进入下一个循环
4、想要中断循环,删除一个lock文件即可,见stop参数

#!/usr/bin/env bash
#set -x

name=realsync
lockfile=/var/lock/subsys/realsync.lock

# Source function library.
. /etc/rc.d/init.d/functions

case "$1" in
start)
echo -n $"Starting $name: "
touch $lockfile
while true ;do
[ -e $lockfile ] || break
/usr/bin/inotifywait -rqqs -t 300 --event create,modify,delete,attrib,close_write /var/www/
/usr/bin/rsync -aqu /var/www/ 192.168.0.1::web/
sleep 1
mkdir -p /var/log/realsync
echo "$(date +'%F %T') realsync works." >> /var/log/realsync/realsync.log-$(date +%F)
done&
echo
;;
stop)
echo -n $"Stopping $name: "
rm -rf $lockfile
pkill inotifywait
echo
;;
*)
echo $"Usage: $0 {start|stop}"
exit 2
esac
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  实时同步 rsync inotify