Inotify

背景

与传统的cp、tar备份方式相比,rsync具有安全性高、备份迅速、支持增量备份等优点,通过rsync可以解决对实时性要求不高的数据备份需求,例如定期的备份文件服务器数据到远端服务器,对本地磁盘定期做数据镜像等。

随着应用系统规模的不断扩大,对数据的安全性和可靠性也提出的更好的要求,rsync在高端业务系统中也逐渐暴露出了很多不足,首先,rsync同步数据时,需要扫描所有文件后进行比对,进行差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将是非常耗时的。而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式。其次,rsync不能实时的去监测、同步数据,虽然它可以通过linux守护进程的方式进行触发同步,但是两次触发动作一定会有时间差,这样就导致了服务端和客户端数据可能出现不一致,无法在应用故障时完全的恢复数据。基于以上原因,rsync+inotify组合出现了!

概念

Inotify 是一种强大的、细粒度的、异步的文件系统事件监控机制,linux内核从2.6.13起,加入了Inotify支持,通过Inotify可以监控文件系统中添加、删除,修改、移动等各种细微事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools就是这样的一个第三方软件。
在上面章节中,我们讲到,rsync可以实现触发式的文件同步,但是通过crontab守护进程方式进行触发,同步的数据和实际数据会有差异,而inotify可以监控文件系统的各种变化,当文件有任何变动时,就触发rsync同步,这样刚好解决了同步数据的实时性问题。

优缺点

优点
监控文件系统事件变化,通过nfs共享同步工具实现数据同步
缺点
(1)并发如果>200个文件(4-100k),同步会有延迟
(2)脚本推送同步服务的过程中,是增量传输的,影响传输效率
(3)监控到事件时,rsync同步是单线程的,sersync是多线程同步的
(4)inotify实现同步需要编写shell脚本,来实现实时同步

因此引入sersync

sersync

  1. 支持配置文件管理
  2. 真正的守护进程是socket
  3. 可以对失败文件定时重传(定时任务功能实现)
  4. 第三方的http接口
  5. 默认多线程同步

部署

第一步

部署rsync守护进程,参照

第二步

  • 部署inotify监控服务

    dnf install -y inotify-tools

  • 熟悉命令用法

    • /usr/bin/inotifywait — 监控目录数据信息变化
    • /usr/bin/inotifywatch — 对监控的变化信息进行统计
  • inotifywait命令使用方法:

    inotifywait [参数] 监控的目录

    • -m|–monitor — 实现一直监控目录的数据变化
    • -r|–recursive — 进行递归监控
    • -q|–quiet — 尽量减少信息的输出
    • –format <fmt> — 指定输出信息的格式
    • –timefmt — 指定输出的时间信息格式
    • -e|–event — 指定监控的事件信息

    监控的事件:

    • access 访问,读取文件。
    • modify 修改,文件内容被修改。
    • attrib 属性,文件元数据被修改。
    • move 移动,对文件进行移动操作。
    • create 创建,生成新文件
    • open 打开,对文件进行打开操作。
    • close 关闭,对文件进行关闭操作。
    • delete 删除,文件被删除。

    示例:

    inotifywait -mrq --timefmt '%d/%m/%y/%H:%M' --format '%T %w %f' -e modify,delete,create,attrib /data

    image-20200503161920915

第三步

  • 下载sersync

    https://github.com/wsgzao/sersync

  • 解压安装

    1
    2
    [root@nfs01 tools]# tar -xf sersync2.5.4_64bit_binary_stable_final.tar
    [root@nfs01 tools]# mv GNU-Linux-x86/ /usr/local/
  • 配置文件部分说明

    • 排除指定数据信息不要进行实时传输同步

      1
      2
      3
      4
      5
      6
      <filter start="false">
      <exclude expression="(.*)\.svn"></exclude>
      <exclude expression="(.*)\.gz"></exclude>
      <exclude expression="^info/*"></exclude>
      <exclude expression="^static/*"></exclude>
      </filter>
    • 定义inotify程序需要监控的事件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <inotify>
      <delete start="true"/>
      <createFolder start="true"/>
      <createFile start="false"/>
      <closeWrite start="true"/>
      <moveFrom start="true"/>
      <moveTo start="true"/>
      <attrib start="false"/>
      <modify start="false"/>
      </inotify>
    • 一般需要修改的地方

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <sersync>
      <localpath watch="/data">
      <remote ip="172.16.1.41" name="backup"/>
      <!--<remote ip="192.168.8.39" name="tongbu"/>-->
      <!--<remote ip="192.168.8.40" name="tongbu"/>-->
      </localpath>
      <rsync>
      <commonParams params="-artuz"/>
      <auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/>
      <userDefinedPort start="false" port="874"/><!-- port=874 -->
      <timeout start="false" time="100"/><!-- timeout=100 -->
      <ssh start="false"/>
      </rsync>

      • localpath watch=”/data”—–本机要进行监控的目录
      • remote ip=“172.16.1.41” name=“backup” ——进行实时同步的另一台服务器ip和模块
      • commonParams params=”-artuz” ———-进行rsync传输时的参数
        auth start=“true” users=“rsync_backup” passwordfile=”/etc/rsync.password”
        表示开启认证服务,认证用户resync_backup ,用户密码保存文件/etc/rsync.password
      • useDefinePort start=“true” port=“873” ———开启端口认证,端口号873
      • timeout start=“true” time=“100” ————— 超时100s,则断开连接

第四步

  • 将sersync2加入环境变量

    [root@nfs01 local]# mv GNU-Linux-x86/sersync2 ./bin/

  • 参数说明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [root@nfs01 local]# sersync2 -h
    set the system param
    execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
    execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
    parse the command param
    _______________________________________________________
    参数-d:启用守护进程模式
    参数-r:在监控前,将监控目录与远程主机用rsync命令推送一遍
    c参数-n: 指定开启守护线程的数量,默认为10个
    参数-o:指定配置文件,默认使用confxml.xml文件
    参数-m:单独启用其他模块,使用 -m refreshCDN 开启刷新CDN模块
    参数-m:单独启用其他模块,使用 -m socket 开启socket模块
    参数-m:单独启用其他模块,使用 -m http 开启http模块
    不加-m参数,则默认执行同步程序
    ________________________________________________________________
  • 开启服务

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    [root@nfs01 local]# sersync2 -dro  /usr/local/GNU-Linux-x86/confxml.xml 
    set the system param
    execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
    execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
    parse the command param
    option: -d run as a daemon
    option: -r rsync all the local files to the remote servers before the sersync work
    option: -o config xml name: /usr/local/GNU-Linux-x86/confxml.xml
    daemon thread num: 10
    parse xml config file
    host ip : localhost host port: 8008
    daemon start,sersync run behind the console
    use rsync password-file :
    user is root
    passwordfile is /etc/rsync.password
    config xml parse success
    please set /etc/rsyncd.conf max connections=0 Manually
    sersync working thread 12 = 1(primary thread) + 1(fail retry thread) + 10(daemon sub threads)
    Max threads numbers is: 22 = 12(Thread pool nums) + 10(Sub threads)
    please according your cpu ,use -n param to adjust the cpu rate
    ------------------------------------------
    rsync the directory recursivly to the remote servers once
    working please wait...
    execute command: cd /data && rsync -artuz -R --delete ./ root@172.16.1.41::backup --password-file=/etc/rsync.password >/dev/null 2>&1
    run the sersync:
    watch path is: /data
  • 关闭服务

    因为sersync不是使用yum方式下载的,所以不能使用systemctl stop rersync的方式停止,可以采用杀死进程的方式停止服务,killall命令需要下载psmisc软件包,dnf install -y psmisc

    [root@nfs01 local]# killall sersync2

  • 加入开机自启

    [root@nfs01 local]# echo "sersync2 -dro /usr/local/GNU-Linux-x86/confxml.xml" >>/etc/rc.local

验证

  1. 主机backup已开启;主机web01通过NFS服务已经挂载到主机nfs01的/data目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@web01 ~]# mount -t nfs 172.16.1.31:/data /mnt
    [root@web01 ~]# df -h
    文件系统 容量 已用 可用 已用% 挂载点
    devtmpfs 383M 0 383M 0% /dev
    tmpfs 399M 0 399M 0% /dev/shm
    tmpfs 399M 11M 388M 3% /run
    tmpfs 399M 0 399M 0% /sys/fs/cgroup
    /dev/mapper/cl-root 3.5G 1.6G 1.9G 46% /
    /dev/sda1 976M 190M 720M 21% /boot
    172.16.1.31:/data 3.5G 1.8G 1.8G 50% /mnt
  2. 在主机web01下创建文件

    [root@web01 mnt]# touch 1.txt

    在主机backup中会实时同步

    1
    2
    [root@backup backup]# ls
    1.txt