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

1. inotify

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

inotify-tools 命令使用讲解

Inotify 内核版本支持

  • 从 kernel 2.6.13 开始, Inotify 正式并入内核,RHEL5 已经支持.
  • 看看是否有 /proc/sys/fs/inotify / 目录,以确定内核是否支持
 [root@RHEL5 Rsync]# ls -l /proc/sys/fs/inotify/
total
-rw-r--r-- root root Oct : max_queued_events
-rw-r--r-- root root Oct : max_user_instances
-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 太小需要调整参数后再次使用.

实例:

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 的用法

实例

rsync -azcvR /data /backup

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

3.inotify+rsync 同步

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

代码

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

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

优化:

#!/bin/bash

src=/home/dahu/Homework/daqing                           # 需要同步的源路径
des=/home/dahu/Homework/daqing.bk # 目标服务器上 cd ${src} # 此方法中,由于 rsync 同步的特性,这里必须要先 cd 到源目录,inotify 再监听 ./ 才能 rsync 同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果 function myfunc { #检测父文件夹是否存在
if [ -d $(dirname $) ]
then
echo "$(dirname $1)"
else
dir=`dirname $`
myfunc $dir
fi
} true && {
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}') # 获取事件
INO_FILE=$(echo $file | awk '{print $2}') # 获取文件 echo "-------------------------------$(date)------------------------------------"
echo $file
#增加、写入完成、移动进事件
if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]
then
echo 'CREATE or CLOSE_WRITE or MOVED_TO'
rsync -avzcuR $(dirname ${INO_FILE}) ${des}
#仅仅更新新的东西,需要加个u,也就是跳过所有已经存在于 DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件)
fi #修改事件
if [[ $INO_EVENT =~ 'MODIFY' ]]
then
echo 'MODIFY'
rsync -avzcR ${INO_FILE} ${des}
#修改文件,只需要同步该文件即可
fi #删除、移动出事件
if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
then
echo 'DELETE or MOVED_FROM'
rsync -avzuR --delete $(myfunc ${INO_FILE}) ${des}
#看 rsync 命令 如果直接同步已删除的路径 ${INO_FILE} 会报 no such or directory 错误 所以这里同步的源是被删文件或目录的上一级路径,并加上 --delete 来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。这里有更好方法的同学,欢迎交流。
fi #修改属性事件 指 touch chgrp chmod chown 等操作
if [[ $INO_EVENT =~ 'ATTRIB' ]]
then
echo 'ATTRIB'
if [ ! -d "$INO_FILE" ] # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync 会顺带更新此目录。
then
rsync -avzcuR ${INO_FILE} ${des}
fi
fi
done
}

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

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

增加文件或文件夹的,更新文件夹目录,注意这里的更新,是指 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点提出的疑问,重复次数不会很多,暂时测试效果还可以。

cat tt.sh
#!/bin/bash src=/home/dahu/Homework/daqing # 需要同步的源路径
des=/home/dahu/Homework/daqing.bk # 目标服务器
cd `dirname $src`
rm -rf log*
inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib,close_write,move `basename $src` > log & function testdir { #显示存在的最深的文件夹
#echo 'hehe'
if [ -d $(dirname $) ]
then
echo "$(dirname $1)"
else
dir=`dirname $`
testdir $dir
fi
} #myfunc daqing/p/q/r/s/t #2s一次循环
cyclenum=`wc -l log |awk '{print $1+1}'`
while true
do
lastnum=$cyclenum
sleep
sec=`date +%S`
if [ `expr $sec % ` = "" ]
then
#date
#这种方法是失效的,why,因为> ,文件删除或者move,就不会再继续往里添加文件了,所以按指定行数来显示比较靠谱
#cat log > log.
#md1=`md5sum log|awk '{print $1}'` && md2=`md5sum log.|awk '{print $1}'`
#if [ $md1 != $md2 ] ;then echo "md5 not equal" && continue ;fi
#touch log. && mv log. log && cat log. >> log.all
cyclenum=`wc -l log |awk '{print $1+1}'`
#sed -n '94,2p'
sed -n "${lastnum},${cyclenum}p" log > log. #这一轮的操作, 暂时证明这个方法是可用的
#sed -n "${lastnum},${cyclenum}p" log >> log.all #用来检测是否漏掉监控的操作
sort -u log. > log.uniq for line in `grep "MODIFY" log.uniq|awk '{print $2}'`
do
#echo $line
if [ -f $line ] ;then rsync -avzcR $line $des;fi
done
for line in `awk '{print $2}' log.uniq`
do
dir=`testdir $line`
rsync -avzuR --delete $dir $des
done
fi
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. nltk30_Investigating bias with NLTK

    sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...

  2. 2008ZJOI树的统计

    codevs 2460 树的统计 http://codevs.cn/problem/2460/ 2008年省队选拔赛浙江  题目等级 : 大师 Master   题目描述 Description 一棵 ...

  3. [转]extern与头文件(*.h)的区别和联系

    用#include可以包含其他头文件中变量.函数的声明,为什么还要extern关键字? 如果我想引用一个全局变量或函数a,我只要直接在源文件中包含#include<xxx.h> (xxx. ...

  4. 对一道pwnhub的一点点记录

    一.通过ssh弱口令,建立socket5代理进内网. 1.修改proxychains配置文件vi /etc/proxychains.conf如下: 2.建立ssh隧道:ssh -qTfnN -D 70 ...

  5. [转]C++ 取代switch的三种方法

    1.常规switch enum EnumType { enumOne, enumTwo, enumThree }; void showMessage(int type) { switch(type) ...

  6. ubuntu复制文件或目录

    转自http://www.linuxidc.com/Linux/2008-11/17179.htm cp(copy)命令 该命令的功能是将给出的文件或目录拷贝到另一文件或目录中. 语法: cp [选项 ...

  7. Once you eliminate all the other factors,the only thing remaining must be the truth.

    Once you eliminate all the other factors,the only thing remaining must be the truth. 一旦你排除了杂因,剩下的一定是 ...

  8. EPC摘抄

    S6a MME – HSS 完成用户位置信息的交换和用户签约信息的管理,传送控制面信息 Diameter MME:主要负责信令处理及移动性管理,功能包括:NAS信令及其安全:跟踪区域(Tracking ...

  9. 移动端Touch事件

    案例1: <!doctype html> <html lang="en"> <head> <meta charset="UTF- ...

  10. Ibatis.Net 各类的作用说明学习(三)

    Ibatis中,加载.分析配置及映射文件是在创建SqlMapper实例的时候进行的,另外对数据库的操作,也是在SqlMapper实例上调用方法来完成.创建SqlMapper的实例的方式是: ISqlM ...