Rsync结合Inotify 实现Centos文件实时同步更新

一. 背景

随着应用系统规模的不断扩大,对数据的安全性和可靠性也提出的更好的要求,rsync在高端业务系统中也逐渐暴露出了很多不足,首先,rsync同步数据时,需要扫描所有文件后进行比对,进行差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将是非常耗时的。而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式。其次,rsync不能实时的去监测、同步数据,虽然它可以通过linux守护进程的方式进行触发同步,但是两次触发动作一定会有时间差,这样就导致了服务端和客户端数据可能出现不一致,无法在应用故障时完全的恢复数据。基于以上原因,rsync+inotify组合出现了!

恩,这是抄的别人的一句话,参见http://www.cnblogs.com/davidwang456/p/3684945.html

inotify 介绍

inotify是一种强大的、细粒度的、异步的文件系统事件控制机制。linux内核从2.6.13起,加入了inotify支持,通过inotify可以监控文件系统中添加、删除、修改、移动等各种事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools正是实施监控的软件。

二. 安装Rsync

2.1 测试环境准备
主机名 主机IP 系统版本 用户
inotify-master 10.211.55.5 Centos 6.5 siyuantlw
inotify-slave 10.211.55.6 Centos 6.5 siyuantlw
2.2 inotify-slave 环境部署
步骤:

检查是否安装Rsync服务
用户及目录准备
Rsync daemon配置
启动Rsync服务
inotify-master测试推送

2.2.1 检查是否安装Rsync服务

[root@inotify-slave ~]# rpm -aq rsync  
rsync-3.0.6-12.el6.x86_64

2.2.2 用户及目录准备


#创建用户并设置密码 useradd siyuantlw passwd siyuantlw #创建Web目录并修改权限 mkdir -p /data/www chown siyuantlw:siyuantlw /data/www/ #创建配置文件目录及文件 mkdir -p /data/server/conf/ touch /data/server/conf/rsync.secret touch /data/server/conf/rsyncd.conf #输入密码 echo "siyuantlw:your_password" > /data/server/conf/rsync.secret #修改权限 chmod 0600 /data/server/conf/rsync.secret

2.2.3 配置Rsync Daemon

vim /data/server/conf/rsyncd.conf `插入以下内容`

uid = siyuantlw
gid = siyuantlw
use chroot = yes
#port = 2222
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
lock file = /var/run/rsyncd.lock
max connections = 10240
timeout = 600
hosts allow = 10.211.55.4/8
hosts deny = *
ignore errors = yes
read only = no
auth users = siyuantlw
secrets file = /data/server/conf/rsync.secret

[www]
path = /data/www

[files]
path = /data/soft

2.2.4 启动Rsync服务

#启动服务
/usr/bin/rsync --daemon --config=/data/server/conf/rsyncd.conf

ps -ef |grep rsync
#如下
root      3520     1  0 16:52 ?        00:00:00 /usr/bin/rsync --daemon --config=/etc/rsyncd/rsyncd.conf

netstat -lnutp |grep rsync
#如下
tcp        0      0 0.0.0.0:873                 0.0.0.0:*                   LISTEN      3520/rsync
tcp        0      0 :::873                      :::*                        LISTEN      3520/rsync

#配置iptables,开放873端口(rsync默认873端口)
vi /etc/sysconfig/iptables
...

# Ps:未配置时会出现,rsync: failed to connect to X.X.X.X: No route to host (113)错误

# 可以添加开机启动  vi /etc/rc.d/rc.local

2.2.5 inotify-master测试推送

#配置密码文件
echo "your_password" > /data/server/conf/rsync.password
chmod 600 /data/server/conf/rsync.password

rsync -avzr ./rsync_test siyuantlw@10.211.55.6::www --password-file=/data/server/conf/rsync.password
#如下
sending incremental file list

sent 79 bytes  received 9 bytes  176.00 bytes/sec
total size is 33  speedup is 0.38

#inotify-slave 确认文件是否正常同步

三. 配置inotify

3.1 inotify简介

Inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删除、读、写和卸载操作等。您还可以跟踪活动的源头和目标等细节。【了解更多】

3.2 查看系统是否支持inotify

#查看当前系统是否支持inotify
ll /proc/sys/fs/inotify/

总用量 0
-rw-r--r-- 1 root root 0 10月 10 18:20 max_queued_events
-rw-r--r-- 1 root root 0 10月 10 18:20 max_user_instances
-rw-r--r-- 1 root root 0 10月 10 18:20 max_user_watches
#显示这三个文件表示支持。

3.3 下载安装

wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar zxf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify
make && make install

说明
/proc/sys/fs/inotify/max_queued_evnets
表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
/proc/sys/fs/inotify/max_user_instances
表示每一个real user ID可创建的inotify instatnces的数量上限。
/proc/sys/fs/inotify/max_user_watches
表示每个inotify instatnces可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小。
例如: echo 30000000 > /proc/sys/fs/inotify/max_user_watches

3.4 编写监控脚本并加载到后台执行

[root@inotify-master scripts]# cat inotify.sh   
#!/bin/bash
#para
host01=10.211.55.6  #inotify-slave的ip地址
src=/data/www/        #本地监控的目录
dst=www         #inotify-slave的rsync服务的模块名
user=siyuantlw     #inotify-slave的rsync服务的虚拟用户
rsync_passfile=/data/server/conf/rsync.password  #本地调用rsync服务的密码文件
inotify_home=/usr/local/inotify    #inotify的安装目录
#judge
if [ ! -e "$src" ] \
|| [ ! -e "${rsync_passfile}" ] \
|| [ ! -e "${inotify_home}/bin/inotifywait" ] \
|| [ ! -e "/usr/bin/rsync" ];
then
echo "Check File and Folder"
exit 9
fi
${inotify_home}/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write,delete,create,attrib $src \
| while read file
do
#  rsync -avzP --delete --timeout=100 --password-file=${rsync_passfile} $src $user@$host01::$dst >/dev/null 2>&1
cd $src && rsync -aruz -R --delete ./  --timeout=100 $user@$host01::$dst --password-file=${rsync_passfile} >/dev/null 2>&1
done
exit 0

[root@inotify-master scripts]# sh inotify.sh &  #将脚本加入后台执行
[1] 13438
[root@inotify-master scripts]#

3.5 实时同步测试

inotify-master操作:
[root@inotify-master scripts]# cd /data/www/
[root@inotify-master www]# ll
总用量 0
[root@inotify-master www]# for a in `seq 200`;do touch $a;done #创建200个文件
[root@inotify-master www]# ll --time-style=full-iso
总用量 0
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.141497569 +0800 1
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.172497529 +0800 10
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.235497529 +0800 100
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.236497529 +0800 101
-rw-r--r-- 1 root root 0 2014-04-22 15:34:08.237497529 +0800 102

inotify-slave检查:

[root@inotify-slave www]# ll  --time-style=full-iso
总用量 0
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 1
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 10
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 100
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 101
-rw-r--r--. 1 rsync rsync 0 2014-04-22 15:34:08.393823754 +0800 102

3.6 排除文件

—配置Inotify—

#借助于--exclude 和 --fromfile参数

inotifywait -mrq --exclude "(.swp|.inc|.svn|.rar|.tar.gz|.gz|.txt|.zip|.bak)" --fromfile '/data/server/script/inotify_exclude.list'

#附. inotify_exclude.list
/data/www/web
@/data/www/web/app/Runtime/
#注:以@开头的路径代表的是要排除的目录和文件,其他的为要监控的文件

—配置Rsync—

#借助于--exclude-from参数
rsync -aruz -R --exclude-from='/data/server/script/rsync_exclude.list'

#附. rsync_exclude.list
app/Runtime
#注:相对路径

—最终Inotify脚本—

#!/bin/bash
#para
host01=10.26.241.199  #inotify-slave的ip地址
src=/data/www/vxb/        #本地监控的目录
dst=www         #inotify-slave的rsync服务的模块名
user=siyuantlw     #inotify-slave的rsync服务的虚拟用户
rsync_passfile=/data/server/conf/rsync-slave.password  #本地调用rsync服务的密码文件
inotify_home=/usr/local/inotify    #inotify的安装目录
inotify_exclude="--fromfile /data/server/script/inotify_exclude.list"
#RSYNC_EXCLUDE="--include-from=/data/conf/shell/rsync_include.list --exclude-from=/data/conf/shell/rsync_exclude.list"
rsync_exclude="--exclude-from=/data/server/script/rsync_exclude.list"
#judge
if [ ! -e "$src" ] \
|| [ ! -e "${rsync_passfile}" ] \
|| [ ! -e "${inotify_home}/bin/inotifywait" ] \
|| [ ! -e "/usr/bin/rsync" ];
then
echo "Check File and Folder"
exit 9
fi
${inotify_home}/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' $inotify_exclude -e close_write,delete,create,attrib $src \
| while read file
do
#  rsync -avzP --delete --timeout=100 $rsync_exclude --password-file=${rsync_passfile} $src $user@$host01::$dst >/dev/null 2>&1
cd $src && rsync -aruz -R --delete ./  --timeout=100 $rsync_exclude $user@$host01::$dst --password-file=${rsync_passfile} >/dev/null 2>&1
done
exit 0

附录

一. inotify之inotifywait常用命令说明  
[root@inotify-master inotify-tools-3.14]# cd /usr/local/inotify-3.14/  
[root@inotify-master inotify-3.14]# ./bin/inotifywait --help  
-r|--recursive   Watch directories recursively. #递归查询目录  
-q|--quiet      Print less (only print events). #打印监控事件的信息  
-m|--monitor   Keep listening for events forever.  Without this option, inotifywait will exit after one  event is received.        #始终保持事件监听状态  
--excludei <pattern>  Like --exclude but case insensitive.    #排除文件或目录时,不区分大小写。  
--timefmt <fmt> strftime-compatible format string for use with %T in --format string. #指定时间输出的格式  
--format <fmt>  Print using a specified printf-like format string; read the man page for more details.  
\#打印使用指定的输出类似格式字符串  
-e|--event <event1> [ -e|--event <event2> ... ] Listen for specific event(s).  If omitted, all events are  listened for.   #通过此参数可以指定需要监控的事件,如下所示:  
Events:  
access           file or directory contents were read       #文件或目录被读取。  
modify           file or directory contents were written    #文件或目录内容被修改。  
attrib            file or directory attributes changed      #文件或目录属性被改变。  
close            file or directory closed, regardless of read/write mode   #文件或目录封闭,无论读/写模式。  
open            file or directory opened                    #文件或目录被打开。    
moved_to        file or directory moved to watched directory    #文件或目录被移动至另外一个目录。  
move            file or directory moved to or from watched directory    #文件或目录被移动另一个目录或从另一个目录移动至当前目录。  
create           file or directory created within watched directory     #文件或目录被创建在当前目录  
delete           file or directory deleted within watched directory     #文件或目录被删除  
unmount         file system containing file or directory unmounted  #文件系统被卸载  
二. rsync的命令格式可以为:
  1. rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
  2. rsync [OPTION]... [USER@]HOST:SRC DEST
  3. rsync [OPTION]... SRC [SRC]... DEST
  4. rsync [OPTION]... [USER@]HOST::SRC [DEST]
  5. rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
  6. rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]

  rsync有六种不同的工作模式:

  1. 拷贝本地文件;当SRC和DES路径信息都不包含有单个冒号":"分隔符时就启动这种工作模式。
  2.使用一个远程shell程序(如rsh、ssh)来实现将本地机器的内容拷贝到远程机器。当DST路径地址包含单个冒号":"分隔符时启动该模式。
  3.使用一个远程shell程序(如rsh、ssh)来实现将远程机器的内容拷贝到本地机器。当SRC地址路径包含单个冒号":"分隔符时启动该模式。
  4. 从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含"::"分隔符时启动该模式。
  5. 从本地机器拷贝文件到远程rsync服务器中。当DST路径信息包含"::"分隔符时启动该模式。
  6. 列远程机的文件列表。这类似于rsync传输,不过只要在命令中省略掉本地机信息即可。
  -a 以archive模式操作、复制目录、符号连接 相当于-rlptgoD

  rsync中的参数

  -r 是递归
  -l 是链接文件,意思是拷贝链接文件;-p 表示保持文件原有权限;-t 保持文件原有时间;-g 保持文件原有用户组;-o 保持文件原有属主;-D 相当于块设备文件;
  -z 传输时压缩;
  -P 传输进度;
  -v 传输时的进度等信息,和-P有点关系,自己试试。可以看文档;
  -e ssh的参数建立起加密的连接。
  -u只进行更新,防止本地新文件被重写,注意两者机器的时钟的同时
  --progress是指显示出详细的进度情况
  --delete是指如果服务器端删除了这一文件,那么客户端也相应把文件删除,保持真正的一致
  --password-file=/password/path/file来指定密码文件,这样就可以在脚本中使用而无需交互式地输入验证密码了,这里需要注意的是这份密码文件权限属性要设得只有属主可读。

使用rsync -aP --exclude=upload 只能排除upload文件/目录。
如果要排除多个文件/目录,怎么办?
  那只能建一个exclude.list,里面填写要排除的目录(一行一个文件/目录),然后rsync -aP --exclude-from=“exclude.list“
如:rsync -aP  --exclude-from=/root/exclude.list 192.168.113.118::web_bak/www/ /data/server/www/    (从118同步数据到本机)
补充
     --exclude=PATTERN       exclude files matching PATTERN
     --exclude-from=FILE     read exclude patterns from FILE
     --include=PATTERN       don't exclude files matching PATTERN
     --include-from=FILE     read include patterns from FILE

内容参考

http://www.cnblogs.com/jackyyou/p/5681126.html
http://www.cnblogs.com/davidwang456/p/3684945.html

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注