rsync+inotify实现文件同步

一、前言

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

二、rsync基本用法

man下文档可以发现,rysnc语法有如下

       Local:  rsync [OPTION...] SRC... [DEST]

       Access via remote shell:
         Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
         Push: rsync [OPTION...] SRC... [USER@]HOST:DEST

       Access via rsync daemon:
         Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
               rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
         Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
               rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

2.1、工作模式

从中也可以看出rsync工作有3中模式

1.本地模式

2.远程shell模式,可以利用ssh协议承载远程传输过程

3.服务模式,此时rsync工作为一个守护进程,能接收客户端的数据同步请求。rsync守护进程依赖于xinetd进程。

2.2、参数说明

sync命令的选项:

    -n    :同步测试,不执行真正的执行过程
    -v    :详细输出模式
    -q    :静默模式
    -c    :checksum,开启校验功能
    -r    :递归复制
    -a    :归档,保留文件的原属性
    -p    :保留文件的权限
    -t    :保留文件的时间戳
    -l    :保留符号连接
    -g    :保留属组
    -o    :保留属主
    -D    :保留设备文件
    -e    ssh    :使用ssh作为传输承载
    -z    :压缩后传输
    --progress    :显示进度条
   --stats    :显示如何执行压缩和传输
   --password-file    :指定密码文件
   --delete    :删除目标目录多余的文件
注意:rsync命令中,如果源路径是目录,且其复制路径时末尾有/,则会复制目录中的内容,而非目录本身,如果末尾 没有/,则会同步目录本身中的所有文件,目标路径末尾是否有/无关紧要
更多的选项解释请自行查看manual。

三、inotify基本用法

inotify在2.6.13内核上是默认支持的,其只是一个用C语言写的api。如果要调用这个api需要编写代码调用。但是有个工具:inotify-tools工具帮我们省去了这一步骤。我们直接调用inotify-tools提供的命令便可监控文件系统的变化。inotify-tools工具epel源中有提供,否则请执行编译安装。Inotify-tools工具安装后提供了两个命令

/usr/bin/inotifywait :监控文件系统变化

  /usr/bin/inotifywatch :用来统计文件系统访问的次数

3.1、inotifywait用法

inotifywait  [-hcmrq] [-e <event> ] [-t <seconds> ] [--format <fmt> ] [--timefmt<fmt> ] <file> [ ... ]
-h	:帮助
-c	:输出CSV(comma-separated values)格式
-m	:监控
-r	:递归
-q	:安静模式
-e	:事件
-t	:超时
--timefmt		:设置事件格式
--format		:输出指定格式
更多的选项解释请自行查看manual。

四、rsync服务器搭建

rsync服务器上

[root@vm ~]# cat /etc/rsyncd.conf 
# Global Setting
uid = nobody                            #运行rsync服务器的用户角色
gid = nobody                            #运行rsync服务器的组角色
use chroot = no                        #是否允许切换根目录
max connections = 10                   #最大连接数
strict modes = yes                     #使用严格策略模式
pid file = /var/run/rsyncd.pid         #pid文件
log file = /var/log/rsyncd.log         #日志文件
#Directory to be synced
[data]                                    #module name
path = /data                            #存放路径
ignore errors = yes                    #传输出错时是否中断传输
read only = no                         #只读
write only = no                        #只写
hosts allow = 192.168.0.0/16           #允许主机范围
hosts deny = *                         #拒绝主机范围
uid = root                              #以什么身份角色工作于/data目录下,可覆盖全局配置
gid = root
auth users = leon                      #认证用户,必须是密码文件中的一个
secrets file = /etc/rsync.passwd       #密码问
建立密码文件
[root@vm tmp]# cat /etc/rsync.passwd  #密码文件
leon:leon                                 #用户:密码   形式存储
重启服务
[root@vm ~]# service xinetd start     #启动xinetd进程
设置iptables
[root@vm ~]# iptables -t filter -A INPUT -d 192.168.226.128 -p tcp --dport=873 -j ACCEPT        #放行策略
[root@vm ~]# iptables -t filter -A OUTPUT -s 192.168.226.128 -p tcp --sport=873 -j ACCEPT       #放行策略
mkdir /data                                                                                                 #建立存储目录

rsync客户端上

建立密码文件
[root@vm ~]# cat /etc/rsync.passwd                     #建立密码文件
leon

[root@vm tmp]# iptables -t filter -A INPUT -s 192.168.226.128 -p tcp --sport=873 -j ACCEPT    #放行策略
[root@vm tmp]# iptables -t filter -A OUTPUT -d 192.168.226.128 -p tcp --dport=873 -j ACCEPT    #放行策略

两台主机都设置selinux为permissive

setenforce 0

测试:在客户端上测试

[root@vm ~]# rsync -avz --progress --delete --password-file=/etc/rsync.passwd leon@192.168.226.128::data /data
receiving incremental file list
created directory /data                        #在客户端上把文件pull到服务器
./
aa
           0 100%    0.00kB/s    0:00:00 (xfer#1, to-check=2/4)
bb
           0 100%    0.00kB/s    0:00:00 (xfer#2, to-check=1/4)
tom/

sent 99 bytes  received 218 bytes  634.00 bytes/sec
total size is 0  speedup is 0.00
[root@vm ~]# ls /data
aa  bb  tom
[root@vm ~]#

在客户端上配仓库,监控同步脚本

[root@vm tmp]# cat /etc/yum.repos.d/epel.repo 
[epel]
name=epel
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-$releasever&arch=$basearch
enabled=1
gpgcheck=0
[root@vm tmp]# yum install -y inotify-tools
[root@vm data]# cat /tmp/rsyncInotify.sh     #此脚本利用inotify机制监控到文件变化时,通过管道的方式实现触发功能,把文件push到服务器上
#!/bin/bash                                        
#
host='192.168.226.128'
user='leon'
monitorFile='/data/'
dest='data'
passwdFile='/etc/rsync.passwd'
inotifywait -mrq -e modify,attrib,moved_to,moved_from,move,move_self,create,delete,delete_self --timefmt='%d/%m/%y %H:%M' --format='%T %w%f %e' $monitorFile | while read chgeFile ;do
rsync -avqz --delete --progress --password-file=$passwdFile $monitorFile $user@$host::$dest &>>/var/log/messages
done

客服端测试

[root@vm data]# sh -n /tmp/rsyncInotify.sh                #检测语法
[root@vm tmp]# nohup /tmp/rsyncInotify.sh &                #后台运行脚本
[root@vm tmp]# jobs
[1]+  Terminated              nohup /tmp/rsyncInotify.sh
[root@vm tmp]# nohup: ignoring input and appending output to `nohup.out'

[root@vm tmp]# jobs
[1]+  Running                 nohup /tmp/rsyncInotify.sh &
[root@vm tmp]# touch /data/leon.rsyncInotify

在服务器上

[root@vm data]# ls
first.txt  first.txtf  hello  leon.rsyncInotify
查看日志
[root@vm data]# tail /var/log/messages
Oct 27 14:44:54 vm xinetd[31417]: START: rsync pid=32950 from=::ffff:192.168.226.129
Oct 27 14:44:54 vm xinetd[31417]: EXIT: rsync status=0 pid=32950 duration=0(sec)
Oct 27 14:45:49 vm xinetd[31417]: START: rsync pid=32956 from=::ffff:192.168.226.129
Oct 27 14:45:50 vm xinetd[31417]: START: rsync pid=32958 from=::ffff:192.168.226.129
Oct 27 14:45:50 vm xinetd[31417]: EXIT: rsync status=0 pid=32956 duration=1(sec)
Oct 27 14:45:50 vm xinetd[31417]: EXIT: rsync status=0 pid=32958 duration=0(sec)
[root@vm data]# tail /var/log/rsyncd.log 
2015/10/27 14:45:49 [32956] connect from UNKNOWN (192.168.226.129)
2015/10/27 14:45:49 [32956] rsync to data/ from leon@unknown (192.168.226.129)
2015/10/27 14:45:50 [32956] receiving file list
2015/10/27 14:45:50 [32956] ./
2015/10/27 14:45:50 [32958] name lookup failed for 192.168.226.129: Name or service not known
2015/10/27 14:45:50 [32958] connect from UNKNOWN (192.168.226.129)
2015/10/27 14:45:50 [32956] sent 98 bytes  received 193 bytes  total size 0
2015/10/27 14:45:50 [32958] rsync to data/ from leon@unknown (192.168.226.129)
2015/10/27 14:45:50 [32958] receiving file list
2015/10/27 14:45:50 [32958] sent 76 bytes  received 154 bytes  total size 0

五、总结

对于rsync+inotify这个方式不适宜海量文件需要同步的情况,对于小规模应用还是可以的。rsync还有许多的参数实现不同的功能可选择,请自行查看manual。epel源中有许多可用软件包,对比国内阿里,搜狐等镜像还多。所以,你懂得,赶紧配一个去。

原创文章,作者:成吉思汗,如若转载,请注明出处:http://www.178linux.com/9084

评论列表(1条)

  • stanley
    stanley 2015-10-31 22:24

    非常赞! 已置顶! 同时如果有delete操作最好增加备份机制

联系我们

400-080-6560

在线咨询

工作时间:周一至周五,9:30-18:30,节假日同时也值班

QR code