什么是rsync,remote synchronize远程同步简写。Linux系统上由rsync这个软件包提供。rsync有几个特点,镜像保存整个文件目录树或文件系统;有较高的数据传输效率;可以借助ssh实现安全数据传输;支持匿名传输等。rsync同步只是针对变化的文件进行传输,意味着其会在源和目标之间比较文件的异同。相对与scp来说,第一次传输两边都效率都差不多。但以后传输相同目录下的文件时,rsync只传输变化的文件,而非像scp直接覆盖。inotify是linux的一种文件变化通知机制,用来监控文件系统的操作,linux内核2.6.13以上支持inotify。rsync和inotify经常搭配使用实现跨主机实时同步。由于rsync要对比源和目标的文件差异。在海量小文件的时候,使用起来效率低;下面以实例说明rsync与inotify的应用:


1.rsync+inotify文件实时同步实现拓扑图:

wKioL1cYoEbCg6a7AAEuk0mCC1k544.bmp

2.系统网络环境部署:

hostname
ip address
kernel-versionkernel-release
rsyncmaster
eth0:172.16.100.7
CentOS release 6.5 (Final)2.6.32-431.el6.x86_64
webserver
eth0:172.16.100.8
CentOS release 6.5 (Final)2.6.32-431.el6.x86_64
ftpserver
eth0:172.16.100.9
CentOS release 6.5 (Final)2.6.32-431.el6.x86_64

3.部署webserver、ftpserver

将webserver、ftpserver部署为rsync服务,以daemon工作模式提供服务

3.1安装rsync、xinetd服务:

[root@webserver ~]# yum -y install rsync xinetd

[root@ftpserver ~]# yum -y install rsync xinetd

3.2新建rsync用户及模块目录并更改其用户组

配置webserver:
[root@webserver ~]# useradd rsync -s /sbin/nologin 
[root@webserver ~]# grep rsync /etc/passwd
rsync:x:500:500::/home/rsync:/sbin/nologin
[root@webserver ~]# mkdir -p /web/htdocs
[root@webserver ~]# ll -d /web/htdocs/
drwxr-xr-x. 2 root root 4096 Apr 21 18:17 /web/htdocs/
[root@webserver ~]# chown -R rsync.rsync /web/htdocs/
[root@webserver ~]# ll -d /web/htdocs/
drwxr-xr-x. 2 rsync rsync 4096 Apr 21 18:17 /web/htdocs/
配置ftpserver:
[root@ftpserver ~]# useradd rsync -s /sbin/nologin 
[root@ftpserver ~]# grep rsync /etc/passwd
rsync:x:500:500::/home/rsync:/sbin/nologin
[root@ftpserver ~]# mkdir -p /web/htdocs
[root@ftpserver ~]# ll -d /web/htdocs/
drwxr-xr-x. 2 root root 4096 Apr 21 18:19 /web/htdocs/
[root@ftpserver ~]# chown -R rsync.rsync /web/htdocs/
[root@ftpserver ~]# ll -d /web/htdocs/
drwxr-xr-x. 2 rsync rsync 4096 Apr 21 18:19 /web/htdocs/

3.3编写rsync daemon配置文件/etc/rsyncd.conf

配置webserver:
[root@webserver ~]# cat /etc/rsyncd.conf
#rsyncd.conf Global Settings#
#工作中指定用户(需要指定用户)
uid = rsync
gid = rsync
#相当于黑洞.出错定位
use chroot = no
#有多少个客户端同时传文件
max connections = 5
#超时时间
timeout = 300
#进程号文件
pid file = /var/run/rsyncd.pid
#日志文件
lock file = /var/run/rsyncd.lock
#日志文件
log file = /var/log/rsyncd.log
#模块开始
#这个模块对应的是推送目录
#模块名称随便起
[htdocs]
#需要同步的目录
path = /web/htdocs/
#表示出现错误忽略错误
ignore errors
#表示网络权限可写(本地控制真正可写)
read only = false
#这里设置IP或让不让同步
list = false
#指定允许的网段
hosts allow = 172.16.0.0/16
#拒绝链接的地址,一下表示没有拒绝的链接。
hosts deny = 192.168.0.0/24
#不要动的东西(默认情况)
#虚拟用户
auth users = rsync_web
#虚拟用户的密码文件
secrets file = /etc/rsync.passwd
#配置文件的结尾

配置ftpserver:
[root@webserver ~]# cat /etc/rsyncd.conf
#rsyncd.conf Global Settings#
#工作中指定用户(需要指定用户)
uid = rsync
gid = rsync
#相当于黑洞.出错定位
use chroot = no
#有多少个客户端同时传文件
max connections = 5
#超时时间
timeout = 300
#进程号文件
pid file = /var/run/rsyncd.pid
#日志文件
lock file = /var/run/rsyncd.lock
#日志文件
log file = /var/log/rsyncd.log
#模块开始
#这个模块对应的是推送目录
#模块名称随便起
[htdocs]
#需要同步的目录
path = /web/htdocs/
#表示出现错误忽略错误
ignore errors
#表示网络权限可写(本地控制真正可写)
read only = false
#这里设置IP或让不让同步
list = false
#指定允许的网段
hosts allow = 172.16.0.0/16
#拒绝链接的地址,一下表示没有拒绝的链接。
hosts deny = 192.168.0.0/24
#不要动的东西(默认情况)
#虚拟用户
auth users = rsync_web
#虚拟用户的密码文件
secrets file = /etc/rsync.passwd
#配置文件的结尾

3.4创建密码文件,采用这种方式不能使用系统用户对客户端进行认证,所以需要创建一个密码文件,其格式为“username:password”,用户名可以和密码可以随便定义,最好不要和系统帐户一致,同时要把创建的密码文件权限设置为600:

配置webserver:
[root@webserver ~]# echo "rsync_web:123456" >/etc/rsyncd.passwd
[root@webserver ~]# cat /etc/rsyncd.passwd
rsync_web:123456    #注:rsync_web为虚拟用户,123456为这个虚拟用户的密码
[root@webserver ~]# chmod 600 /etc/rsyncd.passwd    #为密码文件提权,增加安全性
[root@webserver ~]# ll /etc/rsyncd.passwd 
-rw-------. 1 root root 17 Apr 21 18:36 /etc/rsyncd.passwd

配置ftpserver:
[root@ftpserver ~]# echo "rsync_web:123456" >/etc/rsyncd.passwd
[root@ftpserver ~]# cat /etc/rsyncd.passwd
rsync_web:123456    #注:rsync_web为虚拟用户,123456为这个虚拟用户的密码
[root@ftpserver ~]# chmod 600 /etc/rsyncd.passwd    #为密码文件提权,增加安全性
[root@ftpserver ~]# ll /etc/rsyncd.passwd 
-rw-------. 1 root root 17 Apr 21 18:38 /etc/rsyncd.passwd

3.5启动rsync服务,编辑/etc/xinetd.d/rsync文件,将其中的disable=yes改为disable=no,并重启xinetd服务,如下:

配置webserver:
[root@webserver ~]# cat /etc/xinetd.d/rsync
service rsync
{
    disable    = no
    flags        = IPv6
    socket_type     = stream
    wait            = no
    user            = root
    server          = /usr/bin/rsync
    server_args     = --daemon
    log_on_failure  += USERID
}

配置ftpserver:
[root@ftpserver ~]# cat /etc/xinetd.d/rsync
service rsync
{
    disable    = no
    flags        = IPv6
    socket_type     = stream
    wait            = no
    user            = root
    server          = /usr/bin/rsync
    server_args     = --daemon
    log_on_failure  += USERID
}

重启xinetd服务,启动rsync服务
配置webserver:
[root@webserver ~]# service xinetd restart
Stopping xinetd:                                           [  OK  ]
Starting xinetd:                                           [  OK  ]
[root@webserver ~]# ss -tnl |grep 873
LISTEN     0      64                       :::873                     :::*   

配置ftpserver:
[root@ftpserver ~]# service xinetd restart
Stopping xinetd:                                           [  OK  ]
Starting xinetd:                                           [  OK  ]
[root@ftpserver ~]# ss -tnl |grep 873
LISTEN     0      64                       :::873                     :::*

3.5通过rsyncmaster测试推送:

[root@rsyncmaster ~]# echo "123456" > /etc/rsyncd.passwd 
[root@rsyncmaster ~]# cat /etc/rsyncd.passwd 
123456
[root@rsyncmaster ~]# chmod 600 /etc/rsyncd.passwd
[root@rsyncmaster ~]# ll /etc/rsyncd.passwd
-rw-------. 1 root root 7 Apr 21 20:02 /etc/rsyncd.passwd
[root@rsyncmaster ~]# echo "Samlee rsync test" > ceshi.sh 
[root@rsyncmaster ~]# cat ceshi.sh 
Samlee rsync test
[root@rsyncmaster ~]# rsync -avz ceshi.sh rsync_web@172.16.100.8::htdocs --password-file=/etc/rsyncd.passwd 
[root@rsyncmaster ~]# rsync -avz ceshi.sh rsync_web@172.16.100.9::htdocs --password-file=/etc/rsyncd.passwd

webserver、ftpserver同步情况检查:

[root@webserver ~]# cat /web/htdocs/ceshi.sh 
Samlee rsync test
[root@ftpserver ~]# cat /web/htdocs/ceshi.sh 
Samlee rsync test

4.部署rsyncmaster配置

4.1查询当前linux系统是否支持inotify:

[root@rsyncmaster ~]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Apr 21 20:11 max_queued_events
-rw-r--r-- 1 root root 0 Apr 21 20:11 max_user_instances
-rw-r--r-- 1 root root 0 Apr 21 20:11 max_user_watches
有上面三个文件说明支持

Tips:

/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

4.2下载inotify源码包并编译安装

[root@rsyncmaster ~]# yum -y install gcc
[root@rsyncmaster ~]# wget 
[root@rsyncmaster ~]# tar xf inotify-tools-3.13.tar.gz 
[root@rsyncmaster ~]# cd inotify-tools-3.13
[root@rsyncmaster inotify-tools-3.13]# ./configure --prefix=/usr/local/inotify-3.13 
[root@rsyncmaster inotify-tools-3.13]# make && make install

4.3inotify之inotifywait命令常用参数详解

[root@rsyncmaster ~]# cd /usr/local/inotify-3.14/
[root@rsyncmaster 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  #文件系统被卸载

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

[root@rsyncmaster ~]# vim inotify.sh
#!/bin/bash
#para
host1=172.16.100.8        #webserver的ip地址
host2=172.16.100.9        #ftpserver的ip地址
src=/web/htdocs/          #本地rsync监控目录
dst=htdocs                #rsync同步目标模块
user=rsync_web            #rsync同步目标指定用户
rsync_passfile=/etc/rsyncd.passwd    #rsync密码文件
inotify_home=/usr/local/inotify-3.13 #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
for HostNum in $host1 $host2
do
rsync -avzP --delete --timeout=100 --password-file=${rsync_passfile} $src $user@$HostNum::$dst &>>/var/log/messages
#cd $src && rsync -aruz -R --delete ./  --timeout=100 $user@$HostNum::$dst --password-file=${rsync_passfile} >/dev/null 2>&1
done
done
exit 0
[root@rsyncmaster ~]# sh inotify.sh & #将脚本加入后台执行(如有需要可脚本加入开机自启动)

4.5rsync实时文件同步测试:

首先在rsyncmaster创建测试文件:

[root@rsyncmaster ~]# cd /web/htdocs/
[root@rsyncmaster htdocs]# ll
total 0
[root@rsyncmaster htdocs]# for i in `seq 500`;do touch $i;done
[root@rsyncmaster htdocs]# ll --time-style=full-iso
total 0
-rw-r--r--. 1 root root 0 2016-04-22 08:54:32.168509046 +0800 1
-rw-r--r--. 1 root root 0 2016-04-22 08:54:32.255509072 +0800 10
-rw-r--r--. 1 root root 0 2016-04-22 08:54:32.763509071 +0800 100
-rw-r--r--. 1 root root 0 2016-04-22 08:54:32.770509074 +0800 101

在webserver检查同步目录:

[root@webserver ~]# ll --time-style=full-iso /web/htdocs/
total 0
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 1
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 10
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 100
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 101

在ftpserver检查同步目录:

[root@ftpserver ~]# ll --time-style=full-iso /web/htdocs/
total 0
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 1
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 10
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 100
-rw-r--r--. 1 rsync rsync 0 2016-04-22 08:54:32.000000000 +0800 101

The end!!

以上rsync结合inotify实现文件实时同步应用。