首先分别介绍inotify 与 rsync的使用,然后用两者实现实时文件同步,最后说一下这样的系统存在什么样的问题。

1. inotify

这个具体使用网上很多,参考

inotify-tools 命令使用讲解

Inotify 内核版本支持

  • 从 kernel 2.6.13 开始, Inotify 正式并入内核,RHEL5 已经支持.
  • 看看是否有 /proc/sys/fs/inotify / 目录,以确定内核是否支持
  1. [root@RHEL5 Rsync]# ls -l /proc/sys/fs/inotify/
  2. total
  3. -rw-r--r-- root root Oct : max_queued_events
  4. -rw-r--r-- root root Oct : max_user_instances
  5. -rw-r--r-- root root Oct : max_user_watches

/proc/sys/fs/inotify/max_queued_events 默认值: 16384 该文件中的值为调用 inotify_init 时分配给 inotify instance 中可排队的 event 的数目的最大值,超出这个值得事件被丢弃,但会触发 IN_Q_OVERFLOW 事件

/proc/sys/fs/inotify/max_user_instances 默认值: 128 指定了每一个 real user ID 可创建的 inotify instatnces 的数量上限

/proc/sys/fs/inotify/max_user_watches 默认值: 8192 指定了每个 inotify instance 相关联的 watches 的上限

注意: max_queued_events 是 Inotify 管理的队列的最大长度,文件系统变化越频繁,这个值就应该越大 
如果你在日志中看到 Event Queue Overflow,说明 max_queued_events 太小需要调整参数后再次使用.

实例:

  1. inotifywait -mrq --timefmt '%y%m%d %H:%M' --format '%T %e %w%f' -o log.txt -e modify,create,delete /data

参数说明

语法:
inotifywait [-hcmrq] [-e ] [-t ] [--format ] [--timefmt ] [ ... ]
参数:
-h,–help
输出帮助信息
@
排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile 
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以 @开头。
-m, –monitor
接收到一个事情而不退出,无限期地执行。默认的行为是接收到一个事情后立即退出。
-d, –daemon
跟–monitor 一样,除了是在后台运行,需要指定–outfile 把事情输出到一个文件。也意味着使用了–syslog。
-o, –outfile 
输出事情到一个文件而不是标准输出。
-s, –syslog
输出错误信息到系统日志
-r, –recursive
监视一个目录下的所有子目录。
-q, –quiet
指定一次,不会输出详细信息,指定二次,除了致命错误,不会输出任何信息。
–exclude 
正则匹配需要排除的文件,大小写敏感。
–excludei 
正则匹配需要排除的文件,忽略大小写。
-t , –timeout 
设置超时时间,如果为 0,则无限期地执行下去。
-e , –event 
指定监视的事件。
-c, –csv
输出 csv 格式。
–timefmt 
指定时间格式,用于–format 选项中的 %T 格式。
–format 
指定输出格式。
%w 表示发生事件的目录
%f 表示发生事件的文件
%e 表示发生的事件
%Xe 事件以 “X” 分隔
%T 使用由–timefmt 定义的时间格式

可监听事件

access 文件读取
modify 文件更改。
attrib 文件属性更改,如权限,时间戳等。
close_write 以可写模式打开的文件被关闭,不代表此文件一定已经写入数据。
close_nowrite 以只读模式打开的文件被关闭。
close 文件被关闭,不管它是如何打开的。
open 文件打开。
moved_to 一个文件或目录移动到监听的目录,即使是在同一目录内移动,此事件也触发。
moved_from 一个文件或目录移出监听的目录,即使是在同一目录内移动,此事件也触发。
move 包括 moved_to 和 moved_from
move_self 文件或目录被移除,之后不再监听此文件或目录。
create 文件或目录创建
delete 文件或目录删除
delete_self 文件或目录移除,之后不再监听此文件或目录
unmount 文件系统取消挂载,之后不再监听此文件系统。

2.rsync

参考 Linux 下 rsync 的用法

实例

  1. rsync -azcvR /data /backup

具体各参数的含义参考链接文件

3.inotify+rsync 同步

参考  真正的 inotify+rsync 实时同步 彻底告别同步慢

代码

  1. #!/bin/bash
  2. /usr/bin/inotifywait -mrq --format '%w%f'-e create,close_write,delete /backup |while read file
  3. #把发生更改的文件列表都接收到 file 然后循环, 下面做的是全量 rsync
  4. do
  5. cd /backup && rsync -az --delete /backup/ rsync_backup@192.168.24.101::backup/--password-file=/etc/rsync.password
  6. done

这个程序有个问题,就是每当inotify检测到有事件发生,都进行同步一次,太麻烦

优化:

  1. #!/bin/bash
  2.  
  3. src=/home/dahu/Homework/daqing # 需要同步的源路径
  4. des=/home/dahu/Homework/daqing.bk # 目标服务器上
  5.  
  6. cd ${src} # 此方法中,由于 rsync 同步的特性,这里必须要先 cd 到源目录,inotify 再监听 ./ 才能 rsync 同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
  7.  
  8. function myfunc { #检测父文件夹是否存在
  9. if [ -d $(dirname $) ]
  10. then
  11. echo "$(dirname $1)"
  12. else
  13. dir=`dirname $`
  14. myfunc $dir
  15. fi
  16. }
  17.  
  18. true && {
  19. inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file # 把监控到有发生更改的 "文件路径列表" 循环
  20. do
  21. INO_EVENT=$(echo $file | awk '{print $1}') # 获取事件
  22. INO_FILE=$(echo $file | awk '{print $2}') # 获取文件
  23.  
  24. echo "-------------------------------$(date)------------------------------------"
  25. echo $file
  26. #增加、写入完成、移动进事件
  27. if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]
  28. then
  29. echo 'CREATE or CLOSE_WRITE or MOVED_TO'
  30. rsync -avzcuR $(dirname ${INO_FILE}) ${des}
  31. #仅仅更新新的东西,需要加个u,也就是跳过所有已经存在于 DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件)
  32. fi
  33.  
  34. #修改事件
  35. if [[ $INO_EVENT =~ 'MODIFY' ]]
  36. then
  37. echo 'MODIFY'
  38. rsync -avzcR ${INO_FILE} ${des}
  39. #修改文件,只需要同步该文件即可
  40. fi
  41.  
  42. #删除、移动出事件
  43. if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
  44. then
  45. echo 'DELETE or MOVED_FROM'
  46. rsync -avzuR --delete $(myfunc ${INO_FILE}) ${des}
  47. #看 rsync 命令 如果直接同步已删除的路径 ${INO_FILE} 会报 no such or directory 错误 所以这里同步的源是被删文件或目录的上一级路径,并加上 --delete 来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。这里有更好方法的同学,欢迎交流。
  48. fi
  49.  
  50. #修改属性事件 指 touch chgrp chmod chown 等操作
  51. if [[ $INO_EVENT =~ 'ATTRIB' ]]
  52. then
  53. echo 'ATTRIB'
  54. if [ ! -d "$INO_FILE" ] # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync 会顺带更新此目录。
  55. then
  56. rsync -avzcuR ${INO_FILE} ${des}
  57. fi
  58. fi
  59. done
  60. }

优化思路就是,把每次不同类型的事件,做一个分解:

修改文件的,只同步该文件即可;

增加文件或文件夹的,更新文件夹目录,注意这里的更新,是指 rsync -u   仅仅进行更新,也就是跳过所有已经存在于 DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件),如果你修改了原文件的内容,但不改变名字,就意味着不同步到DST,所以先把修改内容的情况考虑了

删除文件时,这个时候你再同步,即使使用rsync --delete, 删除那些 DST 中 SRC 没有的文件,但是这个文件夹已经删除了,所以得需要访问他存在的父文件夹,不然会报错

即使这3个优化过了,但还是会慢,为什么?

遇到大文件的情况,或者是简单的用vim 生成文件,这个时候inotify 会监控到很多中间文件(如vim的swp),大文件的各种modify操作,都会监控到,这个时候再用刚刚那个程序,每次监控到一个事件,(即使是优化过了,只值针对该文件,不优化的话要同步所有的),都要同步一次,麻烦且耗时。

假设你生成1G的文件,会监控到100次的modify事件,即同步100次,那就是rsync  100*1G,当然使用-u这个参数会好一点,但是如果是修改大文件又保存呢?想象一下就知道需要不停的同步,况且,必须得等到这些前面的循环都跑完了再跑后面的,这个同步的时间不能做到很及时。  刚刚又实验了一下,7.4M的文件,需要419次

4.自己改进

优化的思路来源于第三点的疑问,我没必要同步那么多次(代码中的-u),在这里我在单位时间(2s)内,先把所有操作去重(针对大文件),把modify和别的操作区分对待,对modify的操作同步对应文件,其余的更新父文件夹,记得加-u 和--delete即可。应该算是解决了第3点提出的疑问,重复次数不会很多,暂时测试效果还可以。

  1. cat tt.sh
  2. #!/bin/bash
  3.  
  4. src=/home/dahu/Homework/daqing # 需要同步的源路径
  5. des=/home/dahu/Homework/daqing.bk # 目标服务器
  6. cd `dirname $src`
  7. rm -rf log*
  8. inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib,close_write,move `basename $src` > log &
  9.  
  10. function testdir { #显示存在的最深的文件夹
  11. #echo 'hehe'
  12. if [ -d $(dirname $) ]
  13. then
  14. echo "$(dirname $1)"
  15. else
  16. dir=`dirname $`
  17. testdir $dir
  18. fi
  19. }
  20.  
  21. #myfunc daqing/p/q/r/s/t
  22.  
  23. #2s一次循环
  24. cyclenum=`wc -l log |awk '{print $1+1}'`
  25. while true
  26. do
  27. lastnum=$cyclenum
  28. sleep
  29. sec=`date +%S`
  30. if [ `expr $sec % ` = "" ]
  31. then
  32. #date
  33. #这种方法是失效的,why,因为> ,文件删除或者move,就不会再继续往里添加文件了,所以按指定行数来显示比较靠谱
  34. #cat log > log.
  35. #md1=`md5sum log|awk '{print $1}'` && md2=`md5sum log.|awk '{print $1}'`
  36. #if [ $md1 != $md2 ] ;then echo "md5 not equal" && continue ;fi
  37. #touch log. && mv log. log && cat log. >> log.all
  38. cyclenum=`wc -l log |awk '{print $1+1}'`
  39. #sed -n '94,2p'
  40. sed -n "${lastnum},${cyclenum}p" log > log. #这一轮的操作, 暂时证明这个方法是可用的
  41. #sed -n "${lastnum},${cyclenum}p" log >> log.all #用来检测是否漏掉监控的操作
  42. sort -u log. > log.uniq
  43.  
  44. for line in `grep "MODIFY" log.uniq|awk '{print $2}'`
  45. do
  46. #echo $line
  47. if [ -f $line ] ;then rsync -avzcR $line $des;fi
  48. done
  49. for line in `awk '{print $2}' log.uniq`
  50. do
  51. dir=`testdir $line`
  52. rsync -avzuR --delete $dir $des
  53. done
  54. fi
  55. done

inotify 与 rsync文件同步实现与问题的更多相关文章

  1. Rsync文件同步

    Rsync文件同步 本章结构 关于rsync 1.一款增量备份工具,remote sync,远程同步,支持本地复制或者与其他SSH.rsync主机同步,官方网站:http://rsync.samba. ...

  2. rsync文件同步、Inotify-tools参数详解

    inotifywait用于等待文件或文件集上的一个待定事件,可以监控任何文件和目录设置,并且可以递归地监控整个目录树: inotifywatch用于收集被监控的文件系统计数据,包括每个inotify事 ...

  3. CentOS系统rsync文件同步 安装配置

    rsync是类unix系统下的数据镜像备份工具,从软件的命名上就可以看出来了——remote sync 它的特性如下: 可以镜像保存整个目录树和文件系统. 可以很容易做到保持原来文件的权限.时间.软硬 ...

  4. rsync 文件同步和备份

    rsync 是同步文件的利器,一般用于多个机器之间的文件同步与备份,同时也支持在本地的不同目录之间互相同步文件.在这种场景下,rsync 远比 cp 命令和 ftp 命令更加合适,它只会同步需要更新的 ...

  5. Rsync文件同步工具

    前段时间因公司需求,需要把备份的文件进行同步保存,后面就想到了我们大家都最熟悉的文件同步工作Rsync,于是就捣鼓了一下午时间,然后总结了下大概过程和参数详情. 首先了解了下rsync同步的大致原理: ...

  6. linux 下的 rsync 文件同步

    rsync是linux下的一款快速增量备份工具Remote Sync,是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限.时间.软硬链接等附加信息.rsync是用 “rsync ...

  7. Rsync文件同步服务器配置

    rsync 是一个Unix/Linux系统下的文件同步和传输工具.rsync是用 “rsync 算法”提供了一个客户机和远程文件服务器的文件同步的快速方法.可以用来做备份或镜像.一.配置文件rsync ...

  8. centos7下rsync+inotify脚本实现文件同步,.NET CORE客户端文件更新后自动重启服务

    源服务器IP:192.168.8.51 目标服务器IP:192.168.8.79 安装前源服务器及目标服务器均需关闭FIREWALLD\SELINUX防火墙 sestatus | grep statu ...

  9. [rsync]——rsync文件同步和备份

    实验环境 (1) Rsync服务器:10.0.10.158 (2) Rsync客户端:10.0.10.173 Rsync服务器端的配置 1. 安装xinetd和rsync # yum install ...

随机推荐

  1. Django paginator and Form

    django  提供的分页器 django 官方链接: https://docs.djangoproject.com/en/1.11/topics/pagination/ django提供了一些类来帮 ...

  2. 「Vue」vue cli3中axios的基本用法

    1.安装axiosnpm i axios -S2.main.js中设置import axios from 'axios'Vue.prototype.$axios = axiosPS:这里有个小坑,ax ...

  3. OpenStack安装部署(二)

    中文文档:http://docs.openstack.org/mitaka/zh_CN/install-guide-rdo/提示:这个中文文档是直接翻译过来的,所以会有很多不通顺的地方. 服务介绍 M ...

  4. python——type()、metaclass元类和精简ORM框架

    1.type()函数 if __name__ == '__main__': h = hello() h.hello() print(type(hello)) print(type(h)) Hello, ...

  5. java基础-引用数据类型之二维数组(Array)

    java基础-引用数据类型之二维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前我们学习过了Java的一维数组,所谓的二维数组就是元素是一堆一维数组的数组,换 ...

  6. 科学计算三维可视化---Mlab基础(改变物体的外观颜色)

    import numpy as np from mayavi import mlab #建立数据 x,y = np.mgrid[-::200j,-::200j] z = *np.sin(x*y)/(x ...

  7. 博世传感器调试笔记(一)----加速度传感器BMA253

    公司是bosch的代理商,最近一段时间一直在公司开发的传感器demo板上调试bosch sensor器件.涉及到的器件有7,8款,类型包括重力加速度.地磁.陀螺仪.温度.湿度.大气压力传感器等.在调试 ...

  8. JavaScript setInterval 与 setTimeout 区别

    setInterval:一直循环调用函数,不会停止:需要用 clearInterval 去停止 setTimeout:只调用一次

  9. 【学习DIV+CSS】2. 学习CSS(一)--CSS控制页面样式

    1. CSS如何控制页面 使用XHTML+CSS布局页面,其中有一个很重要的特点就是“结构与表现相分离”(结构指XHTML,表现指CSS).有人这样描述这种分离的关系,结构XHTML好比一个人,表现C ...

  10. [整理]C中的静态存储区

    静态存储区:即内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.它主要存放静态数据.全局数据和常量.栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些 ...