第1章 inotify简介

1.1 rsync+inotify组合的起源
Rsync(remote sync)远程同步工具,通过rsync可以实现对远程服务器数据增量备份同步,但是rsync自身也有瓶颈,同步数据时,rsync采用核心算法对远程服务器的目标文件进行对比,只进行差异同步,如果服务器文件的数量达到百万甚至是千万量级,那么文件对比将是非常耗时的,而且发生变化的往往只是其中很少的一部分,这是非常低效的方式,Inotify的出现,可以缓解rsync的不足之处,取长补短
1.2 Inotify介绍
Inotify是一种强大的、细粒度的、异步的文件系统事件监控机制,linux内核从2.6.13起,加入了inotify支持,通过Inotify可以监控文件系统添加、删除、移动、修改等各种事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况。而inotify-tools正是实施这样监控的软件
Inotify实际是始终事件驱动机制,它为应用程序监控文件系统事件提供了实时响应事件的机制,而无需通过诸如cron等轮询机制来获取事件。Cron等机制不仅无法做到实时性,而且耗费大量系统资源。相比之下,inotify基于事件驱动,可以做到对事件处理的实时响应,也没有轮询造成的系统资源消耗,是非常自然的事件通知接口,也与自然世界的事件机制相符合。
1.3 Inotify实现的几款软件
inotify-tools、sersync(国人金山周洋)、lsyncd

第2章 实时同步的搭建

2.1 实时同步的拓扑结构
inotify+rsync实时备份总结
2.2 inotify实施前的环境准备
2.2.1 特别注意事项
配置的大前提是rsync daemon服务配置成功
2.2.2 查看服务器内核版本是否支持
[root@nfs01 ~]# uname -r
2.6.32-696.el6.x86_64
2.2.2 服务器环境准备

操作系统 服务器角色 IP地址
CentOS release 6.9 x86_64 NFS服务端(nfs-server) 内网:172.16.1.31/24 外网:10.0.0.31/24
CentOS release 6.9 x86_64 backup服务端 内网:172.16.1.41/24 外网:10.0.0.41/24

 注意:在实际的生产环境中是不要外网的
2.3 安装inotify-tools
2.3.1 添加epel源
[root@nfs01 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
注意:yum安装inotify-tools时需要额外的源,所以要提前安装epel源,否则是安装不了的
2.3.1.1 epel是什么
如果既想获得RHEL的高质量、高性能、高可靠性,又需要方便易用(关键是免费)的软件包更新功能,那么Fedora Project退出的EPEL(Extra Packages for Enterprise linux)正好适合。
EPEL(http://fedoraproject.org/wiki/EPEL)是由Fedora社区打造,为RHEL及衍生发行版如Centos、Scientific Linux等提供高质量软件包的项目
2.3.2 开始安装inotify-tools并进行检查
安装:
[root@nfs01 ~]#yum install inotify-tools -y
查看:
[root@nfs01 ~]#rpm -qa inotify-tools
inotify-tools-3.14-1.el6.x86_64
2.3.3 工具集介绍
该软件包共安装了两个工具(命令),即inotifywait和inotifywatch
inotifywait:在被监控的文件或目录上等待特定文件系统事件(open、close、delete等)发生,执行后处于阻塞状态,适合在脚本中使用
inotifywatch:收集被监视的文件系统使用度统计数据,指文件系统事件发生的次数统计
2.3.4 inotifywait命令常用参数详解

参数 说明 含义
-r --recursive 递归查询目录
-q --quiet 打印很少的信息,仅仅打印监控事件的信息
-m --monitor 始终保持事件监听状态
--format -- 打印使用指定的输出类似格式字符串
--timefmt -- 指定事件输出的格式
-e --event 通过此参数可以指定要监控的事件
access 文件或目录被读取
modify 文件或目录的内容被修改
attrib 文件或目录的属性被改变
close 文件或目录被封闭,无论读/写模式
open 文件或目录被打开
move_to 文件或目录被移动至另外一个目录
move 文件或目录被移动至另外一个目录或从另一个目录移动至当前目录
create 文件或目录被创建在当前目录
delete 文件或目录被删除
umount 文件系统被卸载

 可以用下面的命令可以看到上述参数的详解
[root@nfs01 ~]# inotifywait –help
inotifywait 3.14
Wait for a particular event on a file or set of files.
Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]
Options:
-h|--help Show this help text.
@<file> Exclude the specified file from being watched.
--exclude <pattern>
Exclude all events on files matching the
extended regular expression <pattern>.
--excludei <pattern>
Like --exclude but case insensitive.
-m|--monitor Keep listening for events forever. Without
this option, inotifywait will exit after one
event is received.
-d|--daemon Same as --monitor, except run in the background
logging events to a file specified by --outfile.
Implies --syslog.
-r|--recursive Watch directories recursively.
--fromfile <file>
Read files to watch from <file> or `-' for stdin.
-o|--outfile <file>
Print events to <file> rather than stdout.
-s|--syslog Send errors to syslog rather than stderr.
-q|--quiet Print less (only print events).
-qq Print nothing (not even events).
--format <fmt> Print using a specified printf-like format
string; read the man page for more details.
--timefmt <fmt> strftime-compatible format string for use with
%T in --format string.
-c|--csv Print events in CSV format.
-t|--timeout <seconds>
When listening for a single event, time out after
waiting for an event for <seconds> seconds.
If <seconds> is 0, inotifywait will never time out.
-e|--event <event1> [ -e|--event <event2> ... ]
Listen for specific event(s). If omitted, all events are
listened for.

Exit status:
0 - An event you asked to watch for was received.
1 - An event you did not ask to watch for was received
(usually delete_self or unmount), or some error occurred.
2 - The --timeout option was given and no events occurred
in the specified interval of time.

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
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
2.4 人工测试监控工具
注意:测试需开启两个窗口
2.4.1 测试create
 a窗口执行如下命令:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T %w%f' -e
create /backup
 b窗口执行如下命令:
[root@nfs01 backup]# touch {a..f}
 a窗口监测变化:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T %w%f' -e
create /backup
180318 15:37 /backup/a
180318 15:37 /backup/b
180318 15:37 /backup/c
180318 15:37 /backup/d
180318 15:37 /backup/e
180318 15:37 /backup/f
inotify+rsync实时备份总结
2.4.2 测试delete
 a窗口执行如下命令:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T %w%f' -e
delete /backup
 b窗口执行如下命令:
[root@nfs01 backup]# rm -f a b c
 a窗口监测变化:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T %w%f' -e
delete /backup
180318 15:42 /backup/a
180318 15:42 /backup/b
180318 15:42 /backup/c
inotify+rsync实时备份总结
2.4.3 测试close_write
 a窗口执行如下命令:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T %w%f' -e
close_write /backup
 b窗口执行如下命令:
[root@nfs01 backup]# ls
back_2018-03-15.tar.gz d e f
[root@nfs01 backup]# rm -f d e f
[root@nfs01 backup]# touch close_wait.txt {a..c}.txt
[root@nfs01 backup]# ls
a.txt back_2018-03-15.tar.gz b.txt close_wait.txt c.txt
[root@nfs01 backup]# echo 123456 >a.txt
[root@nfs01 backup]# rm -f a
[root@nfs01 backup]# rm -f a.txt
[root@nfs01 backup]# echo 123456 >close_wait.txt
[root@nfs01 backup]# cat close_wait.txt
123456
[root@nfs01 backup]# ls
back_2018-03-15.tar.gz b.txt close_wait.txt c.txt
 a窗口监测变化:
inotify+rsync实时备份总结
2.4.4 同时测试create、modify、delete
 a窗口执行如下命令:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --timefmt '%d%m%y %H:%M' --format '%T %w%f' -e
delete,close_write,modify /backup/
 b窗口执行如下命令:
[root@nfs01 backup]# ls
back_2018-03-15.tar.gz b.txt close_wait.txt c.txt
[root@nfs01 backup]# rm -f .txt
[root@nfs01 backup]# touch {a..c}.txt
[root@nfs01 backup]# echo "hello world" >a.txt
[root@nfs01 backup]# echo "hello world" >b.txt
 a窗口监测变化:
inotify+rsync实时备份总结
2.4.4 简化事件输出
 a窗口执行如下命令:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --format '%w%f' -e create /backup
 b窗口执行如下命令:
[root@nfs01 backup]# ls
a.txt back_2018-03-15.tar.gz b.txt c.txt
[root@nfs01 backup]# rm -f
.txt
[root@nfs01 backup]# touch {a..c}.txt
[root@nfs01 backup]# echo 111 >d
[root@nfs01 backup]# echo 111 >a.txt
 a窗口监测变化:
[root@nfs01 ~]# /usr/bin/inotifywait -mrq --format '%w%f' -e create /backup
/backup/a.txt
/backup/b.txt
/backup/c.txt
/backup/d
inotify+rsync实时备份总结

第3章 inotify实时监控脚本

3.1 创建脚本存放目录并查看
[root@nfs01 ~]# mkdir -p /server/scripts/
[root@nfs01 ~]# ll -d /server/scripts/
3.2 实时监控脚本

rsync 参数 src user@host::dst rsync_passdfile
rsync -avz /data sync_backup@172.16.1.41::nfslookup --password-file= /etc/rsync.password

3.3 脚本实例
3.3.1 脚本实例1


root@nfs01 ~]# vim /server/scripts/inotify.sh
#!/bin/sh
Path=/data
IP=172.16.1.41
/usr/bin/inotifywait -mrq --format '%w%f' -e close_write,delete $
Path \
|while read file
do
cd $Path &&\
rsync -az “$file” --delete rsync_backup@$IP::nfsbackup \
--password-file=/etc/rsync.password &
done
~
 注意:此方法非常用方法(此方法为精准处理法之一)【此方法为无差异同步,慎用】
 \ 为换行符


3.3.2 脚本实例2


[root@nfs01 ~]# vim /server/scripts/inotify1.sh
#!/bin/bash
Path=/data
Ip=172.16.1.41
/usr/bin/inotifywait -mrq --format '%w%f' -e close_write,delete $
Path \
|while read file
do
if [ -f $file ];then
rsync -az $file --delete rsync_backup@$Ip::nfsbackup \
--password-file=/etc/rsync.password
else
cd $Path &&\
rsync -az ./ --delete rsync_backup@$Ip::nfsbackup \
--password-file=/etc/rsync.password
fi
done


3.4 脚本调试方法
3.4.1 客户端执行如下命令
[root@nfs01 scripts]# sh +x /server/scripts/inotify.sh
3.4.2 backup服务端执行如下命令
[root@backup nfsbackup]# watch ls
3.4.3 测试无误后在执行脚本的命令后加& 表示在后台执行
[root@nfs01 scripts]# /bin/sh /server/scripts/inotify.sh &
# 第4章 inotify+rsync优化脚本
4.1 脚本实例


#!/bin/bash
#chkconfig: 2345 38 46
####################################
#this scripts is created by xxxx
####################################
. /etc/init.d/functions

if [ $# -ne 1 ];then
usage: $0 {start|stop}
exit 1
fi

case "$1" in
start)
/bin/bash /server/scripts/inotify.sh &
echo $$ >/var/run/inotify.pid
if [ ps -ef|grep inotify|wc -l -gt 2 ];then
action "inotify service is started" /bin/true
else
action "inotify service is started" /bin/false
fi
;;
stop)
kill -9 cat /var/run/inotify.pid >/dev/null 2>&1
pkill inotifywait
sleep 2
if [ ps -ef|grep inotify|grep -v grep|wc -l -eq 0 ];then
action "inotify service is stopped" /bin/true
else
action "inotify service is stopped" /bin/false
fi
;;
*)
usage: $0 {start|stop}
exit 1
esac


4.2 创建该脚本并查看
[root@nfs01 ~]# vim /etc/init.d/syncd
[root@nfs01 ~]# cat /etc/init.d/syncd
4.3 给该脚本赋予可执行权限
[root@nfs01 ~]# chmod +x /etc/init.d/syncd
4.4 加入开机自启动并查看
[root@nfs01 ~]# chkconfig --add syncd
[root@nfs01 ~]# chkconfig --list syncd
syncd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
4.5 执行脚本看是否成功
[root@nfs01 ~]# /etc/init.d/syncd start
inotify service is started [ OK ]
[root@nfs01 ~]# ps -ef |grep inotify
root 4636 1 0 16:45 pts/1 00:00:00 /bin/bash /server/scripts/inotify.sh
root 4641 4636 0 16:45 pts/1 00:00:00 /usr/bin/inotifywait -mrq --format %w%f -e close_write,delete /data
root 4642 4636 0 16:45 pts/1 00:00:00 /bin/bash /server/scripts/inotify.sh
root 4648 2157 0 16:45 pts/1 00:00:00 grep inotify
[root@nfs01 ~]# /etc/init.d/syncd stop
inotify service is stopped [ OK ]
[root@nfs01 ~]# ps -ef |grep inotify
root 4664 2157 0 16:45 pts/1 00:00:00 grep inotify
4.6 测试
4.6.1 在nfs客户端建立测试文件
[root@nfs01 ~]# cd /data
[root@nfs01 data]# touch stu{01..100}
4.6.2 在backup服务端查看
[root@backup ~]# cd /nfsbackup/
[root@backup nfsbackup]# ls
stu001 stu008 stu015 stu022 stu029 stu036 stu043 stu050 stu057 stu064 stu071 stu078 stu085 stu092 stu099
stu002 stu009 stu016 stu023 stu030 stu037 stu044 stu051 stu058 stu065 stu072 stu079 stu086 stu093 stu100
stu003 stu010 stu017 stu024 stu031 stu038 stu045 stu052 stu059 stu066 stu073 stu080 stu087 stu094
stu004 stu011 stu018 stu025 stu032 stu039 stu046 stu053 stu060 stu067 stu074 stu081 stu088 stu095
stu005 stu012 stu019 stu026 stu033 stu040 stu047 stu054 stu061 stu068 stu075 stu082 stu089 stu096
stu006 stu013 stu020 stu027 stu034 stu041 stu048 stu055 stu062 stu069 stu076 stu083 stu090 stu097
stu007 stu014 stu021 stu028 stu035 stu042 stu049 stu056 stu063 stu070 stu077 stu084 stu091 stu098
inotify+rsync实时备份总结

上述情况说名测试成功

第5章 /proc/sys/fs/inotify/目录详解

5.1 /proc/sys/fs/inotify/目录下的文件
/proc/sys/fs/inotify/目录下共有三个文件,对inotify机制有一定的限制
[root@nfs01 inotify]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Mar 18 13:03 max_queued_events
-rw-r--r-- 1 root root 0 Mar 18 09:32 max_user_instances
-rw-r--r-- 1 root root 0 Mar 18 13:03 max_user_watches
5.2三个文件的说明
 max_queued_events:设置inotify实例事件(event)队列可容纳的事件数量
 max_user_instances:设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
 max_user_watches:设置inotifywait和inotifywatch命令可以监视的文件数量(单进程)
5.3 inotify事件相关参数的默认大小
[root@nfs01 inotify]# cat max_queued_events max_user_instances max_user_watches
327679
128
50000000
5.4 实战调整
[root@nfs01 ~]# echo 655350 >/proc/sys/fs/inotify/max_user_watches
[root@nfs01 ~]# echo 655350 >/proc/sys/fs/inotify/max_queued_events
[root@nfs01 ~]# cat /proc/sys/fs/inotify/max_queued_events
655350
[root@nfs01 ~]# cat /proc/sys/fs/inotify/max_user_watches
655350
 注意:echo 655350 >/proc/sys/fs/inotify/xxx 设置参数重启会失效,因此想要永久需要追加到/etc/rc.local中

第6章 rsync+inotify实时数据同步并发简单测试

测试脚本为sersync中的脚本
10k-100k的文件
每秒100个并发
inotify+rsync实时备份总结
 结论:经过测试,每秒200个并发文件,数据同步几乎无延迟(小于1秒)

第7章 inotify的优缺点

7.1 优点
 监控文件系统事件变化,通过同步工具实现实时数据同步
7.2 缺点
 并发如果大于200个文件(10k-100k),同步就会有延迟
 监控到事件后,调用rsync同步是单进程的
 上文写的脚本,每次都是全部推送一次,但是确实是增量的,也可以只同步变化的文件,不变化的不理