Linux内核从2.6.13开始,引入了inotify机制。
通过intofity机制,能够对文件系统的变化进行监控,如对文件进行创建、删除、修改等操作,可以及时通知应用程序进行相关事件的处理。
这种响应处理机制,避免了频繁的文件轮询任务,提高了任务的处理效率。
一、检查安装
检查系统内核版本
# uname -a
检查系统是否支持inotify
复制代码
# ls -lsart /proc/sys/fs/inotify
total 0
0 dr-xr-xr-x 0 root root 0 Sep 19 09:38 ..
0 -rw-r--r-- 1 root root 0 Jan 1 13:51 max_user_watches
0 -rw-r--r-- 1 root root 0 Jan 1 13:51 max_user_instances
0 -rw-r--r-- 1 root root 0 Jan 1 13:51 max_queued_events
0 dr-xr-xr-x 0 root root 0 Jan 1 13:51 .
如果出现上面结果说明系统支持inotify
notify是一个API,需要通过开发应用程序进行调用,对于大多数用户来讲这有着许多不便,inotify-tools的出现弥补了这一不足。
inotify-tools是一套组件,它包括一个C库和几个命令行工具,这些命令行工具可用于通过命令行或脚本对某文件系统的事件进行监控。
下载安装
#wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
# tar -zvxf inotify-tools-3.14.tar.gz
# cd inotify-tools-3.14
[root@ inotify-tools-3.14]
# ./configure --prefix=/usr/local/inotify
[root@ inotify-tools-3.14]
# make
[root@ inotify-tools-3.14]
# make install
或者使用yum
yum install inotify-tools
其它的一些notify工具(参考)
inotify 的实现有几款软件
1)inotify-tools,
2)sersync(金山周洋)
3)lsyncd
二、命令讲解
inotify-tools提供的两个命令行工具:
inotifywait:通过inotify API等待被监控文件上的相应事件并返回监控结果
默认情况下,正常的结果返回至标准输出,
诊断类的信息则返回至标准错误输出。
它可以在监控到对应监控对象上指定的事件后退出,也可以进行持续性的监控。
inotifywatch:通过inotify API收集被监控文件或目录的相关事件并输出统计信息。
1.inotifywait:
常用参数:
-m --monitor 始终保持监听状态;默认触发事件即退出。
-r --recursive 递归查询目录
-q|--quiet Print less (only print events). 只打印出监控事件
-qq Print nothing (not even events). 静默输出
-o|--outfile <file> Print events to <file> rather than stdout. 输出文件
-s|--syslog Send errors to syslog rather than stderr. 输出错误日志
–-format 指定输出格式。
%w 表示发生事件的目录
%f 表示发生事件的文件
%e 表示发生的事件
%Xe 事件以“X”分隔,输出事件逗号分割会变为X分隔,使用*作为各项目字段的分割符
–-timefmt 指定时间格式,用于–format选项中的%T格式。%y年 %m月 %d日 %H小时 %M分钟
%T 使用由–timefmt定义的时间格式
-e --event 定义监控的事件,省略此选项项即监控所有事件
可用参数:
Events:
access file or directory contents were read 文件或目录读取
modify file or directory contents were written 文件或目录更改
attrib file or directory attributes changed 文件或目录属性更改
close_write file or directory closed, after being opened in 以只读模式打开的文件或目录被关闭
writeable mode
close_nowrite file or directory closed, after being opened in 以只读模式打开的文件或目录被关闭
read-only mode
close file or directory closed, regardless of read/write mode 文件或目录被关闭,不管它是如何打开的
open file or directory opened 文件或目录被打开
moved_to file or directory moved to watched directory 文件或目录被移入监听目录 即使是在同一目录内移动,此事件也触发
moved_from file or directory moved from watched directory 移除监听目录中的文件或目录 即使是在同一目录内移动,此事件也触发
move file or directory moved to or from watched directory 文件或目录发生移动 包括moved_to和 moved_from
create file or directory created within watched directory 文件或目录被创建
delete file or directory deleted within watched directory 文件或目录被删除
delete_self file or directory was deleted 文件或目录移除,之后不再监听此文件或目录
unmount file system containing file or directory unmounted 文件或目录被卸载
监控信息汇总
做个小实验,监控一个目录
# inotifywait -rm ./test
在另一个终端对目录进行操作
# touch /root/test/abc
# rm /root/test/abc
第一个终端显示的 状态改变
# inotifywait -rm ./test
Setting up watches. Beware: since -r was given, this may take a
while
!
Watches established.
.
/test/
CREATE abc
.
/test/
OPEN abc
.
/test/
ATTRIB abc
.
/test/
CLOSE_WRITE,CLOSE abc
.
/test/
OPEN,ISDIR
.
/test/
CLOSE_NOWRITE,CLOSE,ISDIR
.
/test/
OPEN,ISDIR
.
/test/
CLOSE_NOWRITE,CLOSE,ISDIR
.
/test/
DELETE abc
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 # 以指定事件降序排列
同样做个实验,统计 /home 目录发生事件的次数
# inotifywatch -v -e create -e modify -e delete -t 30 -r /home
在新打开的终端上,创建了4个文件,修改了3个文件内容,删除了一个文件。
等监控的30秒时间到了之后,他就会显示出上面的事件次数报告!
# inotifywatch -v -e create -e modify -e delete -t 30 -r /home
Establishing watches...
Setting up
watch
(es) on
/home
OK,
/home
is now being watched.
Total of 3 watches.
Finished establishing watches, now collecting statistics.
Will listen
for
events
for
60 seconds.
total modify create delete filename
8 3 4 1
/home/
三、实际操作
以下为生产环境 使用脚本:
监控源目标文件,发生变化立刻同步
#!/bin/sh
SRC=/var/www/channel/
DST=/var/www/webroot/channel/
INWT=/usr/local/bin/inotifywait
RSYNC=/usr/bin/rsync
$INWT -mrq -e create,move,delete,modify $SRC | while read D E F;
do
rsync -aHqzt $SRC $DST
done
inotifywait 产生的数据
# inotifywait -mrq -e create,move,delete,modify ./test/
./test/ DELETE abc
目录 事件 文件名
分别写进 D E F变量里,一旦有变量写入立即执行 同步操作
一个复杂的脚本
按照事件类型 分格式写入日志
复制代码
#!/bin/bash
inotifywait -mrq --timefmt '%y/%m/%d %H:%M' --format '%T %w%f %e' --event delete,modify,create,attrib /data/web | while read date time file event
do
case $event in
MODIFY|CREATE|MOVE|MODIFY,ISDIR|CREATE,ISDIR|MODIFY,ISDIR)
echo $event'-'$file'-'$date'-'$time >> /var/log/web_watch.log
;;
MOVED_FROM|MOVED_FROM,ISDIR|DELETE|DELETE,ISDIR)
echo $event'-'$file'-'$date'-'$time /var/log/web_watch.log
;;
esac
done
inotifywait 产生的数据
# inotifywait -mrq --timefmt '%y/%m/%d %H:%M' --format '%T %w%f %e' --event delete,modify,create,attrib ./test/
17/10/10 17:31 ./test/abc CREATE
17/10/10 17:31 ./test/abc ATTRIB
四、inotify 系统参数 优化
在/proc/sys/fs/inotify目录下有三个文件,对inotify机制有一定的限制,
可以增加数值以提高性能
max_queued_events :设置inotify实例事件(event)队列可容纳的事件数量。
如果值太小,会出现"** Event Queue Overflow **"错误,导致监控文件不准确
max_user_instances :设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
max_user_watches :设置inotify命令可以监视的目录数量(单进程)
如果报错 upper limit on inotify watches reached! 即是这个原因
可以用:find /xxx -type d | wc -l 统计,必须保证max_user_watches值大于统计结果
查看参数值:
[root@test01 inotify]# ls
max_queued_events max_user_instances max_user_watches
[root@test01 inotify]# cat *
16384 128 8192
也可用以下命令查看结果:
# sysctl -a | grep max_queued_events
修改方法:
1.直接使用vi 修改数值报错 E667: Fsync failed 无法保存!!
缓存的原因?? 网上也没有明确答案……
网上解决办法 echo 32767 > ./max_queued_events
2.
3.若还不生效,最终修改方法
五、inotify+rsync
Rsync(remote sync)远程同步工具,通过rsync可以实现对远程服务器数据的增量备份同步,但rsync自身也有瓶颈,同步数据时,rsync采用核心算法对远程服务器的目标文件进行比对,只进行差异同步。
我们可以想象一下,如果服务器的文件数量达到了百万甚至千万量级,那么文件对比将是非常耗时的。而且发生变化的往往是其中很少的一部分,这是非常低效的方式。
inotify的出现,可以缓解rsync不足之处,取长补短