背景:
公司有一台OA系统为单机服务器,因磁盘故障,导致OA部分附件丢失,为了规避该问题,计划通过rsync+inotify软件,实现文件备件功能,将附件备份到其他服务器上;
一、环境介绍
源端(需要同步文件的服务器):172.12.6.123,文件目录为/u01/weaverfile/file
目标端(备份文件的服务器):172.12.7.51,文件目录为/file/oafile/weaverfile
操作系统均为:Centos7.4
可以通过rsync --version查看rsync软件的版本。
同步方向:将源端(172.12.6.123)/u01/weaverfile/file目录下的文件增删改实时同步到目标端(172.12.7.51)的/file/oafile/weaverfile下。
二、首先介绍下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 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 or CREATEXISDIR'
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 or DELETEXISDIR'
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/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
至此,同步设置安装完毕!!



