Linux下通过rsync+inotify实现目录实时同步

背景:
公司有一台OA系统为单机服务器,因磁盘故障,导致OA部分附件丢失,为了规避该问题,计划通过rsync+inotify软件,实现文件备件功能,将附件备份到其他服务器上;

一、环境介绍
源端(需要同步文件的服务器):172.12.6.123,文件目录为/u01/weaverfile/file
目标端(备份文件的服务器):172.12.7.51,文件目录为/file/oafile/weaverfile/file
操作系统均为:Centos7.4
可以通过rsync --version查看rsync软件的版本:
此处因两个系统均是Centos7.4,所以rsync版本一致,为:

rsync version 3.0.9 protocol version 30
Copyright © 1996-2011 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
append, ACLs, xattrs, iconv, symtimes

rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you
are welcome to redistribute it under certain conditions. See the GNU
General Public Licence for details.

二、首先介绍下inotify
inotify是Linux内核2.6.13 (June 18, 2005)版本新增的一个子系统(API),它提供了一种监控文件系统(基于inode的)事件的机制,可以监控文件系统的变化如文件修改、新增、删除等,并可以将相应的事件通知给应用程序。该机制由著名的桌面搜索引擎项目beagle引入用于替代此前具有类似功能但存在诸多缺陷的dnotify。

inotify既可以监控文件,也可以监控目录。当监控目录时,它可以同时监控目录及目录中的各子目录及文件的。此外,inotify 使用文件描述符作为接口,因而可以使用通常的文件I/O操作select、poll和epoll来监视文件系统的变化。

inotify-tools提供的两个命令行工具:
inotifywait:通过inotify API等待被监控文件上的相应事件并返回监控结果,默认情况下,正常的结果返回至标准输出,诊断类的信息则返回至标准错误输出。它可以在监控到对应监控对象上指定的事件后退出,也可以进行持续性的监控。
inotifywatch:通过inotify API收集被监控文件或目录的相关事件并输出统计信息。

我们这里用到的是inotifywait工具,下面是对应的参数及事件:

inotify 可以监视的文件系统常见事件包括:
事件名称					事件说明
access					读取文件或目录内容
modify					修改文件或目录内容
attrib					文件或目录的属性改变
close_write				修改真实文件内容
close_nowrite	 
close	 
open					文件或目录被打开
moved_to				文件或目录移动到
moved_from				文件或目录从移动
move					移动文件或目录移动到监视目录
create					在监视目录下创建文件或目录
delete					删除监视目录下的文件或目录
delete_self	 
unmount					卸载文件系统

inotify 参数:

参数名称						参数说明
-m,–monitor					始终保持事件监听状态
-r,–recursive				递归查询目录
-q,–quiet					只打印监控事件的信息
–excludei					排除文件或目录时,不区分大小写
-t,–timeout					超时时间
–timefmt					指定时间输出格式
–format						指定时间输出格式
-e,–event					后面指定删、增、改等事件

检查是否支持 inotify

[root@oadb inotify]# ll /proc/sys/fs/inotify
总用量 0
-rw-r--r-- 1 root root 0 12月 23 13:12 max_queued_events
-rw-r--r-- 1 root root 0 12月 23 13:12 max_user_instances
-rw-r--r-- 1 root root 0 12月 23 13:12 max_user_watches

通过/proc接口中的如下参数设定inotify能够使用的内存大小:
1、/proc/sys/fs/inotify/max_queue_events
应用程序调用inotify时需要初始化inotify实例,并时会为其设定一个事件队列,此文件中的值则是用于设定此队列长度的上限;超出此上限的事件将会被丢弃;
2、/proc/sys/fs/inotify/max_user_instances
此文件中的数值用于设定每个用户ID(以ID标识的用户)可以创建的inotify实例数目的上限;
3、/proc/sys/fs/inotify/max_user_watches
此文件中的数值用于设定每个用户ID可以监控的文件或目录数目上限;

三、安装rsync和inotify

3.1目标端安装rsync(先安装目标端172.12.7.51)
安装前可以通过命令进行查看是否安装:

[root@oadb inotify]# rpm -qc rsync
/etc/rsyncd.conf
/etc/sysconfig/rsyncd

如果有没有安装,执行如下命令,前提需要将系统盘挂载好,配置好Yum
Centos 7.4yum配置:
首先将/etc/yum.repos.d/CentOS-Base.repo文件重命名为CentOS-Base.repo.bak

#mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
然后修改CentOS-Media.repo文件如下:
vi /etc/yum.repos.d/CentOS-Media.repo

[c7-media]
name=CentOS-$releasever - Media
baseurl=file:///mnt/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

挂在光盘到/mnt目录:

#mount /dev/cdrom  /mnt

目标端安装rsync:

#yum install rsync -y

安装完以后加入开机启动

#echo 'rsync --daemon' >> /etc/rc.d/rc.local

设置rsync密码(不是系统用户密码),并修改权限

#echo 'admin:1234567' > /etc/rsyncd.scrt
#chmod 600 /etc/rsyncd.scrt

配置rsync.conf文件
配置文件(/etc/rsyncd.conf)

#vi /etc/rsyncd.conf
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:

uid = root
gid = root
use chroot = no
max connections = 10
port = 873
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
log format = %t %a %m %f %b
syslog facility = local3
timeout = 300
 
[OA]
path = /file/oafile/weaverfile/file
comment = rsync info
ignore errors
read only = no
list = no
auth users = admin
secrets file = /etc/rsyncd.scrt
#exclude = * #不需要备份的目录
#exclude from = /etc/rsync_exclude.txt #不备份的目录
hosts allow = 172.12.6.123/255.255.255.0
hosts deny = *

启动rsync

#rsync --daemon

3.2源端安装rsync和inotify
在源端安装rsync(172.12.6.123)
安装前可以通过命令进行查看是否安装:

[root@oadb inotify]# rpm -qc rsync
/etc/rsyncd.conf
/etc/sysconfig/rsyncd

安装rsync:

#yum install rsync -y

安装完以后加入开机启动

#echo 'rsync --daemon' >> /etc/rc.d/rc.local

设置rsync密码(不是系统用户密码),并修改权限

#echo '1234567' > /etc/rsyncd.scrt
#chmod 600 /etc/rsyncd.scrt

配置rsync.conf文件
配置文件(/etc/rsyncd.conf)

#vi /etc/rsyncd.conf
# /etc/rsyncd: configuration file for rsync daemon mode

# See rsyncd.conf man page for more options.

# configuration example:

# uid = nobody
# gid = nobody
# use chroot = yes
# max connections = 4
# pid file = /var/run/rsyncd.pid
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2

# [ftp]
#        path = /home/ftp
#        comment = ftp export area
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:

启动rsync

#rsync --daemon

在源端安装notify:

安装包分为源码和rpm包,下载地址如下:
源码下载地址:http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
rpm包下载页面:http://rpm.pbone.net/index.php3/stat/4/idpl/15265939/dir/redhat_el_5/com/inotify-tools-3.14-1.el5.i386.rpm.html

本案例通过源码安装:

[root@inotify-master]# wget  http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
[root@inotify-master]# tar zxf inotify-tools-3.14.tar.gz
[root@inotify-master]# cd inotify-tools-3.14
[root@inotify-master inotify-tools-3.14]#   ./configure --prefix=/usr/local/include/   
 [root@inotify-master inotify-tools-3.14]#   make && make install  

安装完inotify后对inotifywait进行测试分析:

[root@oadb bin]# /usr/local/include/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move /u01/weaverfile/file
CREATE /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip
CLOSE_WRITEXCLOSE /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip
MODIFY /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip
MODIFY /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip
MODIFY /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip
MODIFY /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip
MODIFY /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip
CLOSE_WRITEXCLOSE /u01/weaverfile/file/202112/S/067e5762-565c-428c-b310-6dda1b52c9ed.zip

得出的结果显示,第一列为事件,第二列是发生事件的路径

要做到实时,就必须要减少rsync对目录的递归扫描判断,尽可能的做到只同步inotify监控到已发生更改的文件。结合rsync的特性,所以这里要分开判断来实现一个目录的增删改查对应的操作。
在源端设置脚本,脚本如下:

#vi /root/rsync_ino.sh
#!/bin/bash
src=/u01/weaverfile/file                           # 需要同步的源路径
des=OA                             # 目标服务器上 rsync --daemon 发布的名称,rsync --daemon这里就不做介绍了,网上搜一下,比较简单。
rsync_passwd_file=/etc/rsyncd.scrt            # rsync验证的密码文件
ip1=172.12.7.51                 # 目标服务器1
user=admin                          # rsync --daemon定义的验证用户名
cd ${src}                            
/usr/local/include/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $file
        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]         # 判断事件类型
        then
                echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}
        fi
        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        then
                echo 'DELETE or MOVED_FROM'
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}
        fi
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}         
                fi
        fi
done

给脚本添加执行权限

#chmod +x /root/rsync_ino.sh

四、执行脚本,验证结果

[root@oadb ~]# sh rsync_ino.sh > rsync_ino.log &

[1] 24080

[root@oadb ~]# tail -f rsync_ino.log 
-------------------------------2021年 12月 24日 星期五 09:02:28 CST------------------------------------
CREATE ./202112/U/536a0421-d6cb-4cfd-b5f0-01e7d00d1a32.zip
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
sending incremental file list
./
202112/U/
202112/U/05975f07-d2fe-4e92-8f17-827c143444c8.zip
202112/U/1040417372.zip
202112/U/1145499273.zip
202112/U/1150692820.zip
202112/U/1217963347.zip
202112/U/1225719111.zip
202112/U/1303346186.zip
202112/U/1579297567.zip
202112/U/1707659339.zip
202112/U/171e9f82-b076-49fc-a879-0854b7e7ed09.zip
202112/U/1759253984.zip
202112/U/1884103102.zip
202112/U/1907833910.zip
202112/U/1969725107.zip
202112/U/1973033628.zip
202112/U/1dcd0ae8-40e5-44bb-8610-436d0d0533f5.zip
202112/U/21bbfdd3-0f63-4ecf-b4c6-a356acc9bbad.zip
202112/U/22825127-7802-47d2-94e1-feb3839d6c45.zip
202112/U/2d453e90-9f11-48db-952a-e35905502bf3.zip
202112/U/3902b136-4195-47b9-8862-b96417d1e1e8.zip
202112/U/3d1e574c-3e25-4253-95bb-e5759a795cbd.zip
202112/U/4208f55e-a59c-4998-97a6-aae08d2e8dd1.zip
202112/U/48c89853-4e89-4407-9661-f6f6f659df6a.zip
202112/U/4eae8196-2d0e-400c-a8fb-fb6a8c51c1f7.zip
202112/U/536a0421-d6cb-4cfd-b5f0-01e7d00d1a32.zip
202112/U/6aced335-42e0-4469-827f-bdae787ddd7a.zip
202112/U/7164bf77-059a-41c5-ad56-90dd83398415.zip
202112/U/74e4d3fc-87a1-4928-ba1d-03a184615c0e.zip
202112/U/7aab9548-0b09-491c-a117-7ecb0ca397fb.zip
202112/U/864e86f1-1759-4b18-8976-2d1e7de31494.zip
202112/U/88dae8e1-67da-49b8-b34a-b5991d9ddf3d.zip
202112/U/8be0c03e-9822-4abf-9eb2-f55ac208e14b.zip
202112/U/8d22b984-3f97-4623-b45c-76925373d074.zip
202112/U/8d43faed-a08a-41a5-80b1-8f1bbdda1ac8.zip
202112/U/9ff6b97e-62ec-411a-888b-370e4b8aa69c.zip
202112/U/a92797c7-a98f-4ec6-a4eb-008722f2bc81.zip
202112/U/b060e9b2-aabc-4de7-837a-02c4fc6560af.zip
202112/U/b10db7ab-8014-4824-97a6-cd674dcb6620.zip
202112/U/c10fcb28-6fa3-493a-b135-24e9e7eea92c.zip
202112/U/c1a68aca-aefa-4bb0-a32e-841ee7a0972d.zip
202112/U/c32f02b8-111c-4806-ac52-708ef3fcbb53.zip
202112/U/ccc7e85c-3821-4d1a-ab41-c2b0cc1556ab.zip
202112/U/cfbc5398-d8a6-4a5c-9c58-2b41f26fa384.zip
202112/U/daf7ebea-f5b9-4e0d-8955-ab2361e34165.zip
202112/U/f6ba5447-2dfb-47ec-8660-53b4870db507.zip
202112/U/fcb73094-120f-4fbc-9b1c-06cc0baa9ecd.zip
202112/U/fcebd7f7-a3cf-4dd7-8ad8-b503ba2040d8.zip
202112/U/fe9ea313-07cb-4b3f-998a-596f9004db91.zip

sent 29292071 bytes  received 929 bytes  1362465.12 bytes/sec
total size is 915383785  speedup is 31.25
-------------------------------2021年 12月 24日 星期五 09:02:49 CST------------------------------------
CLOSE_WRITEXCLOSE ./202112/U/536a0421-d6cb-4cfd-b5f0-01e7d00d1a32.zip
CREATE or MODIFY or CLOSE_WRITE or MOVED_TO
sending incremental file list

至此,同步设置安装完毕!!

上一篇:Java 压缩成zip文件


下一篇:在上线项目中,用Vue写一个星级评价