一、架构说明

  inotify 对同步数据目录信息的监控
  rsync 完成对数据信息的实时同步
inotify+rsync实现非结构化数据实时同步(图文详解)_第1张图片

inotify3.14-9(centos7 64位版本)(阿里云更新时间20191128最新版本)
wget https://mirrors.aliyun.com/epel/7/SRPMS/Packages/i/inotify-tools-3.14-9.el7.src.rpm?spm=a2c6h.13651111.0.0.7dba2f70EEq268&file=inotify-tools-3.14-9.el7.src.rpm

二、inotify的介绍

inotify-tools是为linux下inotify文件监控工具提供的一套C的开发接口库函数,同时还提供了一系列的命令行工具,这些工具可以用来监控文件系统的事件。
inotify-tools是用c编写的,除了要求内核支持inotify外,不依赖于其他。
inotify-tools提供两种工具,一是inotifywait,它是用来监控文件或目录的变化,二是inotifywatch,它是用来统计文件系统访问的次数。我们主要用到的是inotifywait工具。

innotify的三个重要文件
inotify+rsync实现非结构化数据实时同步(图文详解)_第2张图片

文件 默认值 作用说明
max_user_watches 8192 设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)
max_user_instances 128 设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
max_queued_events 16384 设置inotify实例事件(event)队列可容纳的事件数量

三、inotify主要安装的两个软件

inotifywait: (主要)

  在被监控的文件或目录上等待特定文件系统事件(open close delete等)发生,执行后处于阻塞状态,适合在shell脚本中使用

1、inotifywait 参数说明

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

2、inotifywait events事件说明

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

3、inotifywatch:

  收集被监控的文件系统使用的统计数据,指文件系统事件发生的次数统计。
说明:在实时实时同步的时候,主要是利用inotifywait对目录进行监控

四、关于rsync
rsync具有安全性高、备份迅速、支持增量备份等优点,通过rsync可以解决实时性不高的数据备份需求,例如定期数据库备份。
但随着业务规模的扩大,业务需求的增加,rsync的缺点也暴露出来了:

1、当文件数量大到百万级别,rsync仅差异扫描就是一项非常耗时的工作;

2、rsync自身不能实时的检测并同步数据,它总是被动的通过各种方式去触发同步。

五、inotify同步脚本
inotify_rsync.sh

#!/bin/bash
source /etc/profile
src=/data/                           # 需要同步的源路径
des=datahome                             # 目标服务器上 rsync 模块名
rsync_passwd_file=/etc/rsyncd/rsync.passwd            # rsync验证的密码文件
ipaddr=(10.0.0.1)                 # 目标服务器,多个目标服务器以空格分开
user=user                            # rsync --daemon定义的验证用户名
inlogs=/var/log/inotifywait.logs
logs=/var/log/inotify_rsync.logs
errlog=/var/log/inotify_rsync.err.logs
cd ${src}                              # 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
/usr/local/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move --exclude=".*.swp" ./ >> $inlogs &
while true;do
     if [ -s ${inlogs} ];then
        grep -i -E "delete|moved_from" ${inlogs} >> /var/log/inotify_away.log
        for ip in ${ipaddr[@]}
        do
            rsync -avzcR --password-file=${rsync_passwd_file} --exclude="*.swp" --exclude="*.swx" ${src} ${user}@${ip}::${des} >> $logs
            RETVAL=$?
        done
        #同步失败后的输出日志
        if [ $RETVAL -ne 0 ];then
           echo "${src} sync to ${ipaddr} failed at `date +"%F %T"`,please check it by manual" >> $errlog
        fi
        cat /dev/null > $inlogs
        for ip in ${ipaddr[@]}
        do
            rsync -avzcR --password-file=${rsync_passwd_file} --exclude="*.swp" --exclude="*.swx" ${src} ${user}@${ip}::${des} >> $logs
        done
    else
        sleep 1
    fi
done

脚本说明:这个脚本是将inotify的检测内容输出到文件/var/log/inotifywait.logs,脚本判断这个文件是否为空,非空则表明有变动,那么就来一次完整的同步。如果文件为空则睡眠1秒。
优点:不会根据inotify输出重复触发rsync同步。
缺点:每次都是rsync完整同步,如果文件数量较大则对比时间会比较长。

感谢以下三篇文章作者
(https://blog.csdn.net/ronon77/article/details/84763471)
(https://www.cnblogs.com/clsn/p/8022625.html)
(http://www.capjsj.cn/inotify_rsync.html)