本文首发于烂泥行天下。
上篇文章我们介绍了如何使用rsync同步文件,这篇文章我们再来介绍下,如何把rsync与inotify集成实现数据的实时同步。
要达到这个目的,我们需要分以下几个步骤:
1、rsync的优点与不足
2、inotify是什么
3、检测OS是否支持inotify
4、inotify相关参数详解
5、inotify监控的文件事件类似
6、inotify-tools是什么
7、安装inotify-tools
8、inotifywait使用详解
9、inotifywatch使用详解
10、inotif-tools与rsync集成
一、rsync的优点与不足
rsync在Linux/Unix下是一个比较重要和实用的服务,大家应该已经知道rsync具有安全性高、备份迅速、支持增量备份等优点。
通过rsync可以解决对实时性要求不高的数据备份需求,例如:定期备份文件服务器数据到远端服务器,对本地磁盘定期做数据镜像等。
随着应用系统规模的不断扩大,对数据安全性和可靠性也提出了更高的要求,rsync在高端业务系统中也逐渐暴露出它的不足。
首先,rsync在进行同步数据时,需要先扫描所有文件后进行比对,然后再进行差量传输。如果文件数量达到百万甚至千万级,扫描所以文件将是非常耗时的。而且发生变化的往往是其中很少的一部分文件,这是非常低效的方式。
其次,rsync不能实时地去监测、同步数据。虽然它可以通过Linux守护进程的方式触发同步,但是两次触发动作之间一定会有时间差。这样就可能会导致服务端和客户端数据出现不一致的情况,无法在应用出现故障时完全恢复数据。
基于以上原因,所以就考虑采用rsync与inotify集成的方式来解决这些问题。
二、inotify是什么
inotify是一种强大的、细粒度的、异步的文件系统事件监控机制。
Linux内核从2.6.13(2005年8月)起,加入了对inotify的支持,通过inotify可以监控文件系统中的添加、删除、修改、移动等各种细微事件。利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools就是这样一个第三方软件。
在上面章节中,我们讲到,rsync可以实现触发式的文件同步。它是通过crontab守护进程方式触发,同步的数据和实际数据会有差异,而inotify可以监控文件系统的各种变化,当文件有任何变化时,就触发rsync同步,这就刚好解决了数据同步实时性的问题。
三、检测OS是否支持inotify
由于inotify特性需要Linux内核的支持,所以在安装inotify-tools之前要先确认Linux系统内核是否达到2.6.13以上。如果Linux内核低于2.6.23版本,就需要重新编译内核加入对inotify的支持,也可以用如下的方法来判断Linux内核是否支持inotify。
注意:目前本篇文章的OS为centos 6.5 64bit。
cat /etc/system-release
uname -r
ls -lsart /proc/sys/fs/inotify/
只要执行ls -lsart /proc/sys/fs/inotify/命令,如下结果有max_user_watches、max_user_instances、max_queued_events这三个文件,说明centos 6.5 64bit是支持inotify的。
通过上图,我们可以很明显的看到centos 6.5 64bit是支持inotify的。
四、inotify相关参数详解
inotify定义了三个接口参数,可以用来限制inotify消耗kernel memory的大小。由于这些参数都是内存参数,因此,可以根据应用需求实时的调节其大小。下面分别做简单介绍:
/proc/sys/fs/inotify/max_queued_evnets
表示请求events数的最大值,超出这个值的事件将被丢弃。该值默认为16384。
注意:max_queued_events是inotify管理的队列的最大长度,文件系统变化越频繁,这个值就应该越大。
如果你在日志中看到Event Queue Overflow,说明max_queued_events太小需要调整参数后再次使用。
/proc/sys/fs/inotify/max_user_instances
表示每个user可创建的instances数量上限。该值默认为128。
/proc/sys/fs/inotify/max_user_watches
表示可监控目录的最大数。该值默认为8192。
要修改以上默认值,我们可以使用以下类似手段修改。如下:
echo 30000000>/proc/sys/fs/inotify/max_user_watches
五、inotify监控的文件事件类型
inotify可监控的文件系统事件类型,如下:
IN_ACCESS:文件被访问。
IN_MODIFY:文件被write。
IN_ATTRIB:文件属性被修改,如chmod、chown等。
IN_CLOSE_WRITE:可写文件被close。
IN_CLOSE_NOWRITE:不可写文件被close。
IN_OPEN:文件被open。
IN_MOVED_FROM:文件被移出被监控目录,如mv。
IN_MOVED_TO:文件被移入被监控目录,如mv、cp。
IN_CREATE:文件/文件夹被创建。
IN_DELETE:文件/文件夹被删除,如rm。
IN_DELETE_SELF:自删除,即一个可执行文件在执行时删除自己。
IN_MOVE_SELF:自移动,即一个可执行文件在执行时移动自己。
IN_UNMOUNT:宿主文件系统被umount。
IN_CLOSE:文件被关闭,等同于(IN_CLOSE_WRITE|IN_CLOSE_NOWRITE)。
IN_MOVE:文件被移动,等同于(IN_MOVED_FROM|IN_MOVED_TO)。
注意:上面所说的文件也包括目录。
六、inotify-tools是什么
inotify仅仅是一个API,需要通过开发应用程序进行调用。inotify-tools就是这样的一个inotify软件,它是一套组件,包括一个C库和几个命令行工具。这些命令行工具可用于通过命令行或脚本对某些文件系统的事件进行监控。
inotify是为替代dnotify而设计的,它克服了dnotify的缺陷,提供了更好用的,更简洁而强大的文件变化通知机制。
1)inotify不需要对被监视的目标打开文件描述符,而且如果被监视目标在可移动介质上,那么在umount该介质上的文件系统后,被监视目标对应的watch将被自动删除,并且会产生一个umount事件。
2)inotify既可以监视文件,又可以监视目录。
3)inotify使用系统调用而非SIGIO信号来通知文件系统事件。
4)inotify使用文件描述符作为接口,因而可以使用通常的文件I/O操作select和poll来监视文件系统的变化。
七、安装inotify-tools
inotify-tools的安装可以分为源码方式和RPM方式。下面就这两种方式一一讲解。
注意:inotify-tools主要是通过inotifywait和inotifywatch,这两个命令进行工作。特别是inotifywait命令,是我们生产环境中使用最多的命令。
7.1 源码方式安装
源码方式安装inotify-tools,我们可以去inotify-tools官网去下载源码包。
inotify-tools官网:
https://github.com/rvoicilas/inotify-tools/wiki
下载inotify-tools并安装,如下:
注意:不建议使用wget下载inotify-tools,因为我在使用wget下载inotify-tools一直不成功,后来查询相关资料发现是github网站的原因。
wget https://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
我们可以先通过浏览器下载本地,然后通过rz命令上传到服务器。
要使用rz命令,我们需要安装lrzsz软件,如下:
yum -y install lrzsz
lrzsz安装完毕后,我们来上传inotify-tools软件包。如下:
现在开始解压、安装inotify-tools,如下:
tar -xf inotify-tools-3.14.tar.gz
./configure
make&&make install
安装完毕后,我们切换到/usr/local/bin/目录下查看,如下:
cd /usr/local/bin/
通过上图,我们可以看到inotifywait和inotifywatch命令已经被安装到/usr/local/bin/目录下。
7.2 RPM方式安装
要RPM方式安装inotify-tools,我们首先要配置yum源,否则系统会提示找不到inotify-tools这软件包。如下:
我们可以去下面这个连接下载最新的yum源,如下:
http://dl.fedoraproject.org/pub/epel/6/x86_64/
下载epel-release-6-8.noarch.rpm软件包并安装,如下:
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm
以上操作完毕后,我们再来yum安装inotify-tools,如下:
yum �Cy install inotify-tools
查看inotify-tools安装的生成的文件,如下:
rpm -ql inotify-tools
通过上图,我们可以很容易的看到inotifywait和inotifywatch已经被安装到了/usr/bin/目录下。
以上就是有关inotify-tools的安装。
八、inotifywait使用详解
inotify-tools命令中,我们使用最多的就是inotifywait命令。
inotifywait是一个监控等待事件,它主要用于监控文件或目录的变化,并且可以递归地监控整个目录树。
8.1 inotifywait命令详解
有关inotifywait的使用方法,我们可以通过它的帮助信息查看。如下:
inotifywait -h
通过上图,我们可以看到inotifywait参数很多。下面我们就介绍下一些经常使用的参数:
-m表示始终保持事件监听状态。
-r表示递归查询目录。
-q表示打印出监控事件。
-e通过此参数可以指定要监控的事件。可监听的事件,如下:
access:访问,读取文件。
modify:修改,文件内容被修改。
attrib:属性,文件元数据被修改。
move:移动,对文件进行移动操作。以及重命名,对文件进行重命名。
create:创建,生成新文件
open:打开,对文件进行打开操作。
close:关闭,对文件进行关闭操作。
delete:删除,文件被删除。
--timefmt是指定时间的输出格式,用于--format选项中的%T格式。
--format指定文件变化的详细信息输出格式。格式参数如下:
%w表示发生事件的目录
%f表示发生事件的文件
%e表示发生的事件
%T使用由--timefmt定义的时间格式
%Xe事件以“X”分隔
8.2 inotifywait命令实例
8.1章节我们讲解了inotifywait命令的参数,下面我们来实际使用下inotifywait命令。
我们要监测/home目录下所有文件及目录的变化情况,命令如下:
inotifywait -mrq --timefmt '%y/%m/%d/%H:%M' --format '%T %w %f %e' -e modify,delete,create,attrib,move,open,close,access /home/
这条命令表示对/home目录下所有文件及目录的操作进行监控。
现在我们打开另外一个窗口对/home目录进行操作,如下:
我们是在/home目录下创建一个空的文件createfile以及一个新的目录createmkdir。
现在我们来切换到刚刚执行inotifywait命令的窗口,如下:
通过上图,我们可以很容易的看到inotifywait已经监控到我们前面创建的文件以及目录。
九、inotifywatch使用详解
除了inotifywatit命令之外,inotify-tools还有一个命令inotifywatch。
inotifywatch主要用于收集被监控的文件系统统计数据,包括每个inotify事件发生多少次等信息。
9.1 inotifywatch命令详解
inotifywatch使用可以查看其帮助信息,如下:
inotifywatch -h
inotifywatch参数说明如下:
-h:输出帮助信息。
-v:输出详细信息。
@:排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
�C-fromfile:从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-z:输出表格的行和列,即使元素为空。
�C-exclude:正则匹配需要排除的文件,大小写敏感。
�C-excludei:正则匹配需要排除的文件,忽略大小写。
-r:监视一个目录下的所有子目录。
-t:设置超时时间。
-e:只监听指定的事件。该事件与inotifywait监听的事件类型一样。
-a:以指定事件升序排列。
-d:以指定事件降序排列。
9.2 inotifywatch命令实例
9.1章节我们讲解了inotifywatch命令的参数,下面我们来实际使用下inotifywatch命令。
要求统计60秒内/home目录下文件系统的事件,使用如下命令:
inotifywatch -v -e modify,delete,create,attrib,move,open,close,access -e modify -t 60 -r /home
现在我们打开另外一个窗口对/home目录进行操作,如下:
我们是在/home目录下删除一个文件createfile以及重命名createmkdir为test。
现在我们来切换到刚刚执行inotifywatch命令的窗口,如下:
通过上图,我们可以很容易的看到inotifywatch已经监控到我们前面删除的文件和重命名的目录文件事件数量。
十、inotify-tools与rsync集成
inotify-tools与rsync的集成主要是通过inotifywait命令与rsync命令集成来实现的,并且该集成主要是体现的rsync客户端,而rsync服务器端正需要按照正常的配置进行即可。
注意:该集成的主要目的是把rsync客户端需要备份的文件实时推送到rsync服务器上。
有关rsync的配置,可以参考《烂泥:linux文件同步之rsync学习(一)》这篇文章,而且本次实验的环境和这篇文章是同一个环境。
rsync服务器是192.168.199.247,rsync客户端为192.168.199.248。
我们现在的要求是只要rsync客户端的/home/www目录下有任何文件或者目录有改动的情况,都要实时的同步到rsync服务器上。
rsync服务器已经正常运行,相关配置文件如下:
下面我们的所有操作都是在rsync客户端上进行的,其实inotifywait命令与rsync命令集成,我们所要做的只是写一个shell脚本即可。脚本内容如下:
#!/bin/bash
src=/root/www/
dest=www
ip=192.168.199.247
/usr/bin/inotifywait -mrq --timefmt '%d/%m/%y%H:%M' --format '%T %w %f' -e modify,delete,create,attrib $src | while read DATE TIME DIR FILE;
do
filechange=${DIR}${FILE}
/usr/bin/rsync -avz --delete --progress $src apache@$ip::$dest --password-file=/etc/rsyncd.password &
echo "At ${TIME} on ${DATE}, file $filechange was backed up via rsynce" >>/tmp/rsync.log 2>&1
done
在这个脚本中,我只讲解while read DATE TIME DIR FILE这条语句,其他语句请自行查看相关文档。
inotifywait命令产生三个返回值,分别是“日期,时间,文件”这3个返回值会做为参数传给read,因此脚本中的“while read D E F”写法细化了返回值。
该脚本的原理是利用inotifywait命令对指定的文件和目录进行监控,如果指定文件和目录有改变那么就启动rsync同步命令。
上述脚本写好后,我们要给予其执行权限,然后配置其开机后台运行,并启动。使用如下命令:
chmod 700 inotify.sh
chmod u+x inotify.sh
ll |grep inotify.sh
echo "sh /root/inotify.sh > /dev/null &" >>/etc/rc.local
sh inotify.sh > /dev/null &
注意:为了让该脚本启动后台运行,一定要把启动命令写成图中的形式,否则该脚本在进行同步文件时会报如下的信息:
以上配置完毕后,我们来测试看看其效果。在rsync客户端上新建一个文件ilanni.txt,如下:
touch www/ilanni.txt
现在切换rsync服务器上查看刚刚在rsync客户端上创建的文件是否已经同步过来。
通过上图,我们可以很明显的看到文件已经同步过来。
再来rsync客户端查看相关的日志,如下:
可以看到日志中记录同步的时间已经同步的文件。
到此inotify-tools与rsync的集成已经全部配置完毕。