基于inotify+rsync的文件实时同步
2014-07-11 12:40:46   来源:我爱运维网   评论:0 点击:

基于inotify+rsync的文件实时同步如何监控文件的变化并实时同步,很多人都可以随口说出很多的解决方案。最简单的就是自定义脚...
               基于inotify+rsync的文件实时同步
如何监控文件的变化并实时同步,很多人都可以随口说出很多的解决方案。最简单的就是自定义脚本定期扫描文件md5的变化,如果发生了变化,则rsync或是ftp到目的地。当然,也可以通过puppet或cfengine之类的配置管理工具在各个目的机器之间进行实时同步。甚至,还可以参考Amazone的Dynamo的Hash Tree算法,写程序来实时同步。 实时是重点,同步只是辅助。
除了以上三种方案,本文介绍一个基于Linux内核inotify机制的实时同步方案,简单易用,对于有大量小文件需要实时同步的场合,比如网站内容,是个不错的选择。
扩展思路,在某些场合,只要能实时监控到文件的变化,我们就可以对文件进行处理,比如打印某些异常或是某些特征,结合告警,还可以实现服务的监控。

一、           inotify基本介绍
inotify 是一种强大的、细粒度的、异步的文件系统事件监控机制。linux内核从2.6.13起,加入了inotify支持,通过inotify可以监控文件系统中添加、删除,修改、移动等各种事件。
inotify事件由一个inotify_event结构体表示,在内核态,内核在每个inode中增加inotify_watch结构体,组成inotify_watches列表,实时的查看inotify_watches列表就可以实时监控每个inode的变化,最后通过inotify_inode_queue_event函数返回通知。
inotify_inode_queue_event函数通过查看inotify_watches列表是否为空来判断对应的inode是否被监视,如果发现 inode 没有被监视,什么也不做,立刻返回,反之,遍历inotify_watches列表,看是否当前的文件操作事件被某个 watch 监视,如果是,调用inotify_dev_queue_event,否则,返回。
在用户态,inotify 通过系统调用和在inotify_init()返回的文件描述符fd上的文件进行 I/O操作。如果有事件,通过调用read来获取,如果没有事件时就挂在等待队列 wq 上。
   有一些第三方软件inotify-tools,可以监控文件系统下文件的各种变化情况,Google的命令行备份工具Openduckbill其实也是基于inotify机制。Sersync也是基于inotify机制的一个同步软件。
 
   inotify可监听和跟踪的事件有:
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      文件系统取消挂载,之后不再监听此文件系统。
 
二、           inotify-tools安装部署
    由于inotify特性需要Linux内核的支持,在安装inotify-tools前要先确认Linux系统内核是否达到了2.6.13以上,如果Linux内核低于2.6.13版本,就需要重新编译内核加入inotify的支持,也可以用如下方法判断,内核是否支持inotify:
[root@CODOL_SH_TEST01 ~]# uname -r
2.6.32.43-tlinux-1.0.3-default
[root@CODOL_SH_TEST01 ~]#
[root@CODOL_SH_TEST01 ~]# ll /proc/sys/fs/inotify
total 0
-rw-r--r-- 1 root root 0 May 23 15:49 max_queued_events
-rw-r--r-- 1 root root 0 May 26 09:52 max_user_instances
-rw-r--r-- 1 root root 0 May 25 15:49 max_user_watches
[root@CODOL_SH_TEST01 ~]#
    如果有上面三项输出,表示系统已经支持inotify,接着就可以开始安装inotify-tools了。
可以到http://inotify-tools.sourceforge.net/下载相应的inotify-tools版本,然后开始编译安装:
[root@CODOL_SH_TEST01 /data/maplewu/software]# tar zxvf inotify-tools-3.14.tar.gz
[root@CODOL_SH_TEST01 /data/maplewu/software]# cd inotify-tools-3.14
[root@CODOL_SH_TEST01 /data/maplewu/software/inotify-tools-3.14]# ./configure
[root@CODOL_SH_TEST01 /data/maplewu/software/inotify-tools-3.14]# make
[root@CODOL_SH_TEST01 /data/maplewu/software/inotify-tools-3.14]# make check
[root@CODOL_SH_TEST01 /data/maplewu/software/inotify-tools-3.14]# make install
[root@CODOL_SH_TEST01 /data/maplewu/software/inotify-tools-3.14]# cd /usr/local/bin/
[root@CODOL_SH_TEST01 /usr/local/bin]# ls -l inotify*
-rwxr-xr-x 1 root root 44271 Apr 29 09:35 inotifywait
-rwxr-xr-x 1 root root 41345 Apr 29 09:35 inotifywatch
 
    安装完inotify-tools后,在/usr/local/bin目录下会生成inotifywait和inotifywatch两个命令,其中,inotifywait用于等待文件或文件集上的一个特定事件,它可以监控任何文件和目录设置,并且可以递归地监控整个目录树。inotifywatch用于收集被监控的文件系统统计数据,包括每个inotify事件发生多少次等信息。
    inotify定义了下列的接口参数,可以用来限制inotify消耗kernel memory的大小。这些参数都是内存参数,可以根据应用需求,实时的调节其大小。下面分别做简单介绍。
   /proc/sys/fs/inotify/max_queued_evnets    
   max_queued_evnets参数表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
   /proc/sys/fs/inotify/max_user_instances
   max_user_instances参数表示每一个real user ID可创建的inotify instatnces的数量上限。
   /proc/sys/fs/inotify/max_user_watches
   max_user_watches参数表示每个inotify instatnces可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小,例如:
   echo 30000000 > /proc/sys/fs/inotify/max_user_watches
 
三、           inotifywaitinotifywatch使用说明
1)inotifywait
语法:
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定义的时间格式
 
2)inotifywatch
语法:
inotifywatch [-hvzrqf] [-e ] [-t ] [-a ] [-d ] [ ... ]
参数:
-h, –help
输出帮助信息
-v, –verbose
输出详细信息
@排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-z, –zero
输出表格的行和列,即使元素为空
–exclude
正则匹配需要排除的文件,大小写敏感。
–excludei
正则匹配需要排除的文件,忽略大小写。
-r, –recursive
监视一个目录下的所有子目录。
-t , –timeout
设置超时时间
-e , –event
只监听指定的事件。
-a , –ascending
以指定事件升序排列。
-d , –descending
以指定事件降序排列。
 
四、    CODOL Tdirty 脏词文件同步的思考
    CODOL的脏词系统Tdirty比较特殊,采用的是Web同步。即将加密后的脏词文件dirtyword.dat放到apache目录,合作方定期读取该文件,并加载到内存使之生效。
    目前现网部署了两台web server,并不一定要求他们之间完全实时同步,在脏词文件发生变化后手工分别往两台机器同步也是可选方案之一,但是,这不是最优方案。通过inotify+rsync来实现文件的实时自动同步,相比更优,而且易于扩展,即便以后Tdirty机器多了(多个服或是多个大区),也可以轻松应对。
   方案测试如下:
   1)测试信息:
   待监控文件所在机器:CODOL_SH_TEST01
   同步文件机器(rsync服务器):rsync_server
   监视的文件夹:/tmp
   监控的事件:modify、delete、create、attrib
   2)操作步骤:
   (1)使用inotifywait监控/tmp目录的modify、delete、create和attrib事件,如果监控到这四类事件,则将变化的文件rsync到rsync_server上。
基于inotify+rsync的文件实时同步
2)对/tmp目录下的inotify_test文件分别进行create、attrib、delete操作
基于inotify+rsync的文件实时同步
(3)查看文件是否正确上传。通过图1和图3,可以发现当触发上述四个事件中的任意一个,rsync都会将inotify_test文件上传到rsync server上。
基于inotify+rsync的文件实时同步 
如果想监控某个文件或是文件夹的inotify时间统计,可使用能够inotifywatch命令,下面是监视/var目录各个文件的事件统计。
基于inotify+rsync的文件实时同步
   以上是命令行测试,如果想开机后自动监控指定文件或文件夹,并在发生变化时实时同步到其他目录或机器,可将命令写成脚本,放在后台执行,并加入到/etc/rc.local文件。假设脚本名为tdiry_rsync.sh,内容如下:
#!/bin/sh
#src是Tdiry主机上的需要同步的脏词文件路径
src=/data/CODO/ATVI
#desc是Tdirty备机上rsync模块名,对应脏词文件路径(前提是备机已部署好rsync服务)
des=Tdirty
#Tdirty备机的IP地址
ip=xxx.xxx.xxx.xxx
#rsync的用户名 
user=Tdiry
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format  '%T %w%f' 
-e modify,delete,create,attrib ${src} | while read file
 do
#--password-file存放用户${user}的密码。记得权限设置为600    
rsync -avz --delete --progress --password-file=/etc/rsyncd.pass ${src} ${user}@${ip}::${des} &&
 done

加入到/etc/rc.local,以便开机自动监控
echo “tdirty_rsync.sh &” >>/etc/rc.local

相关热词搜索:inotify rsync 同步

上一篇:Linux环境SVN命令行使用经验总结
下一篇:最后一页

分享到: 收藏