第2章 rsync(二):inotify+rsync详细说明和sersync,in

以下是rsync系列篇:
  1.rsync(一):基本命令和用法
  2.rsync(二):inotify+rsync详细说明和sersync
  3.rsync算法原理和工作流程分析
  4.rsync技术报告(翻译)
  5.rsync工作机制(翻译)
  6.man rsync翻译(rsync命令中文手册)

第2章 rsync(二):inotify+rsync详细说明和sersync,inotifyrsync


本文目录:

inotify+rsync

1.1 安装inotify-tools

1.2 inotifywait命令以及事件分析

1.3 inotify应该装在哪里

1.4 inotify+rsync示例脚本(不完善)

1.5 inotify的不足之处

1.5.1 inotify的bug

1.5.2 inotify+rsync的缺陷

1.6 inotify+rsync的最佳实现

sersync



inotify+rsync

如果要实现定时同步数据,可以在客户端将rsync加入定时任务,但是定时任务的同步时间粒度并不能达到实时同步的要求。在Linux kernel 2.6.13后提供了inotify文件系统监控机制。通过rsync+inotify组合可以实现实时同步。

inotify实现工具有几款:inotify本身、sersync、lsyncd。其中sersync是金山的周洋开发的工具,克服了inotify的缺陷,且提供了几个插件作为可选工具。此处先介绍inotify的用法以及它的缺陷,通过其缺陷引出sersync,并介绍其用法。

1.inotify+rsync

如果要实现定时同步数据,可以在客户端将rsync加入定时任务,但是定时任务的同步时间粒度并不能达到实时同步的要求。在Linux kernel 2.6.13后提供了inotify文件系统监控机制。通过rsync+inotify组合可以实现实时同步。

inotify实现工具有几款:inotify本身、sersync、lsyncd。其中sersync是金山的周洋开发的工具,克服了inotify的缺陷,且提供了几个插件作为可选工具。此处先介绍inotify的用法以及它的缺陷,通过其缺陷引出sersync,并介绍其用法。

1.1 安装inotify-tools

inotify由inotify-tools包提供。在安装inotify-tools之前,请确保内核版本高于2.6.13,且在/proc/sys/fs/inotify目录下有以下三项,这表示系统支持inotify监控,关于这3项的意义,下文会简单解释。

[[email protected] tmp]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_queued_events
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_instances
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_watches

epel源上提供了inotify-tools工具,或者下载源码包格式进行编译。

inotify-tools源码包地址:https://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

以下为编译安装过程:

tar xf inotify-tools-3.14.tar.gz
./configure --prefix=/usr/local/inotify-tools-3.14
make && make install
ln -s /usr/local/inotify-tools-3.14 /usr/local/inotify

inotify-tools工具只提供了两个命令。

[[email protected] ~]# rpm -ql inotify-tools | grep bin/
/usr/bin/inotifywait
/usr/bin/inotifywatch

其中inotifywait命令用于等待文件发生变化,所以可以可以实现监控(watch)的功能,该命令是inotify的核心命令。inotifywatch用于收集文件系统的统计数据,例如发生了多少次inotify事件,某文件被访问了多少次等等,一般用不上。

以下是inotify相关的内核参数。

(1)./proc/sys/fs/inotify/max_queued_events:调用inotify_init时分配到inotify instance中可排队的event数的最大值,超出值时的事件被丢弃,但会触发队列溢出Q_OVERFLOW事件。
(2)./proc/sys/fs/inotify/max_user_instances:每一个real user可创建的inotify instances数量的上限。
(3)./proc/sys/fs/inotify/max_user_watches:每个inotify实例相关联的watches的上限,即每个inotify实例可监控的最大目录、文件数量。如果监控的文件数目巨大,需要根据情况适当增加此值。

如:

[[email protected] ~]# echo 30000000 > /proc/sys/fs/inotify/max_user_watches

1.1 安装inotify-tools

inotify由inotify-tools包提供。在安装inotify-tools之前,请确保内核版本高于2.6.13,且在/proc/sys/fs/inotify目录下有以下三项,这表示系统支持inotify监控,关于这3项的意义,下文会简单解释。

[root@node1 tmp]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_queued_events
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_instances
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_watches

epel源上提供了inotify-tools工具,或者下载源码包格式进行编译。

inotify-tools源码包地址:https://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

以下为编译安装过程:

tar xf inotify-tools-3.14.tar.gz
./configure --prefix=/usr/local/inotify-tools-3.14
make && make install
ln -s /usr/local/inotify-tools-3.14 /usr/local/inotify

inotify-tools工具只提供了两个命令。

[root@xuexi ~]# rpm -ql inotify-tools | grep bin/
/usr/bin/inotifywait
/usr/bin/inotifywatch

其中inotifywait命令用于等待文件发生变化,所以可以可以实现监控(watch)的功能,该命令是inotify的核心命令。inotifywatch用于收集文件系统的统计数据,例如发生了多少次inotify事件,某文件被访问了多少次等等,一般用不上。

以下是inotify相关的内核参数。

(1)./proc/sys/fs/inotify/max_queued_events:调用inotify_init时分配到inotify instance中可排队的event数的最大值,超出值时的事件被丢弃,但会触发队列溢出Q_OVERFLOW事件。

(2)./proc/sys/fs/inotify/max_user_instances:每一个real user可创建的inotify instances数量的上限。

(3)./proc/sys/fs/inotify/max_user_watches:每个inotify实例相关联的watches的上限,即每个inotify实例可监控的最大目录、文件数量。如果监控的文件数目巨大,需要根据情况适当增加此值。

如:

[root@xuexi ~]# echo 30000000 > /proc/sys/fs/inotify/max_user_watches

1.2 inotifywait命令以及事件分析

inotifywait命令的选项:

-m:表示始终监控,否则应该是监控到了一次就退出监控了
-r:递归监控,监控目录中的任何文件,包括子目录。递归监控可能会超出max_user_watches的值,需要适当调整该值
@<file>:如果是对目录进行递归监控,则该选项用于排除递归目录中不被监控的文件。file是相对路径还是绝对路径由监控目录是相对还是绝对来决定
-q:--quiet的意思,静默监控,这样就不会输出一些无关的信息
-e:指定监控的事件。一般监控的就delete、create、attrib、modify、close_write
--exclude <pattern> :通过模式匹配来指定不被监控的文件,区分大小写
--excludei <pattern>:通过模式匹配来指定不被监控的文件,不区分大小写
--timefmt:监控到事件触发后,输出的时间格式,可指定可不指定该选项,一般设置为[--timefmt '%Y/%m/%d %H:%M:%S']
--format:用户自定义的输出格式,如[--format '%w%f %e%T']
  %w:产生事件的监控路径,不一定就是发生事件的具体文件,例如递归监控一个目录,该目录下的某文件产生事件,将输出该目录而非其内具体的文件
  %f:如果监控的是一个目录,则输出产生事件的具体文件名。其他所有情况都输出空字符串
  %e:产生的事件名称
  %T:以"--timefmt"定义的时间格式输出当前时间,要求同时定义"--timefmt"

inotifywait -e可监控的事件:

access:文件被访问
modify:文件被写入
attrib:元数据被修改。包括权限、时间戳、扩展属性等等
close_write:打开的文件被关闭,是为了写文件而打开文件,之后被关闭的事件
close_nowrite:read only模式下文件被关闭,即只能是为了读取而打开文件,读取结束后关闭文件的事件
close:是close_write和close_nowrite的结合,无论是何种方式打开文件,只要关闭都属于该事件
open:文件被打开
moved_to:向监控目录下移入了文件或目录,也可以是监控目录内部的移动
moved_from:将监控目录下文件或目录移动到其他地方,也可以是在监控目录内部的移动
move:是moved_to和moved_from的结合
moved_self:被监控的文件或目录发生了移动,移动结束后将不再监控此文件或目录
create:在被监控的目录中创建了文件或目录
delete:删除了被监控目录中的某文件或目录
delete_self:被监控的文件或目录被删除,删除之后不再监控此文件或目录
umount:挂载在被监控目录上的文件系统被umount,umount后不再监控此目录
isdir :监控目录相关操作

以下是几个示例:

[[email protected] ~]# mkdir /longshuai

[[email protected] ~]# inotifywait -m /longshuai   # 以前台方式监控目录,由于没指定监控的事件,所以监控所有事件
Setting up watches.
Watches established.

打开其他会话,对被监控目录进行一些操作,查看各操作会触发什么事件。

[[email protected] ~]# cd  /longshuai    # 进入目录不触发任何事件

(1).向目录中创建文件,触发create、open attrib、close_write和close事件。

[[email protected] longshuai]# touch a.log

/longshuai/ CREATE a.log
/longshuai/ OPEN a.log
/longshuai/ ATTRIB a.log
/longshuai/ CLOSE_WRITE,CLOSE a.log

如果是创建目录,则触发的事件则少的多。

[[email protected] longshuai]# mkdir b

/longshuai/ CREATE,ISDIR b

ISDIR表示产生该事件的对象是一个目录。

(2).修改文件属性,触发attrib事件。

[[email protected] longshuai]# chown 666 a.log

/longshuai/ ATTRIB a.log

(3).cat查看文件,触发open、access、close_nowrite和close事件。

[[email protected] longshuai]# cat a.log

/longshuai/ OPEN a.log
/longshuai/ ACCESS a.log
/longshuai/ CLOSE_NOWRITE,CLOSE a.log

(4).向文件中追加或写入或清除数据,触发open、modify、close_write和close事件。

[[email protected] longshuai]# echo "haha" >> a.log

/longshuai/ OPEN a.log
/longshuai/ MODIFY a.log
/longshuai/ CLOSE_WRITE,CLOSE a.log

(5).vim打开文件并修改文件,中间涉及到临时文件,所以有非常多的事件。

[[email protected] longshuai]# vim a.log

/longshuai/ OPEN,ISDIR
/longshuai/ CLOSE_NOWRITE,CLOSE,ISDIR
/longshuai/ OPEN,ISDIR
/longshuai/ CLOSE_NOWRITE,CLOSE,ISDIR
/longshuai/ OPEN a.log
/longshuai/ CREATE .a.log.swp
/longshuai/ OPEN .a.log.swp
/longshuai/ CREATE .a.log.swx
/longshuai/ OPEN .a.log.swx
/longshuai/ CLOSE_WRITE,CLOSE .a.log.swx
/longshuai/ DELETE .a.log.swx
/longshuai/ CLOSE_WRITE,CLOSE .a.log.swp
/longshuai/ DELETE .a.log.swp
/longshuai/ CREATE .a.log.swp
/longshuai/ OPEN .a.log.swp
/longshuai/ MODIFY .a.log.swp
/longshuai/ ATTRIB .a.log.swp
/longshuai/ CLOSE_NOWRITE,CLOSE a.log
/longshuai/ OPEN a.log
/longshuai/ CLOSE_NOWRITE,CLOSE a.log
/longshuai/ MODIFY .a.log.swp
/longshuai/ CREATE 4913
/longshuai/ OPEN 4913
/longshuai/ ATTRIB 4913
/longshuai/ CLOSE_WRITE,CLOSE 4913
/longshuai/ DELETE 4913
/longshuai/ MOVED_FROM a.log
/longshuai/ MOVED_TO a.log~
/longshuai/ CREATE a.log
/longshuai/ OPEN a.log
/longshuai/ MODIFY a.log
/longshuai/ CLOSE_WRITE,CLOSE a.log
/longshuai/ ATTRIB a.log
/longshuai/ ATTRIB a.log
/longshuai/ MODIFY .a.log.swp
/longshuai/ DELETE a.log~
/longshuai/ CLOSE_WRITE,CLOSE .a.log.swp
/longshuai/ DELETE .a.log.swp

其中有"ISDIR"标识的是目录事件。此外,需要注意到vim过程中,相应的几个临时文件(.swp、.swx和以~为后缀的备份文件)也产生了事件,这些临时文件的相关事件在实际应用过程中,其实不应该被监控。

(6).向目录中拷入一个文件,触发create、open、modify和close_write、close事件。其实和新建文件基本类似。

[[email protected] longshuai]# cp /bin/find .

/longshuai/ CREATE find
/longshuai/ OPEN find
/longshuai/ MODIFY find
/longshuai/ MODIFY find
/longshuai/ CLOSE_WRITE,CLOSE find

(7).向目录中移入和移除一个文件。

[[email protected] longshuai]# mv /tmp/after.log /longshuai

/longshuai/ MOVED_TO after.log

[[email protected] longshuai]# mv /tmp/after.log /longshuai

/longshuai/ MOVED_FROM after.log

(8).删除一个文件,触发delete事件。

[[email protected] longshuai]# rm -f a.log

/longshuai/ DELETE a.log

从上面的测试结果中可以发现,很多动作都涉及了close事件,且大多数情况都是伴随着close_write事件的。所以,大多数情况下在定义监控事件时,其实并不真的需要监控open、modify、close事件。特别是close,只需监控它的分支事件close_write和close_nowrite即可。由于一般情况下inotify都是为了监控文件的增删改,不会监控它的访问,所以一般只需监控close_write即可。

由于很多时候定义触发事件后的操作都是根据文件来判断的,例如a文件被监控到了变化(不管是什么变化),就立即执行操作A,又由于对文件的一个操作行为往往会触发多个事件,例如cat查看文件就触发了open、access、close_nowrite和close事件,这样很可能会因为多个事件被触发而重复执行操作A。例如下面的示例,当监控到了/var/log/messages文件中出现了a.log关键字,就执行echo动作。

while inotifywait -mrq -e modify /var/log/messages; do
  if tail -n1 /var/log/messages | grep a.log; then
    echo "haha"
  fi
done

综合以上考虑,建议对监控对象的close_write、moved_to、moved_from、delete和isdir(主要是create,isdir,但无法定义这两个事件的整体,所以仅监控isdir)事件定义对应的操作,因为它们互不重复。如有需要,可以将它们分开定义,再添加需要监控的其他事件。例如:

[[email protected] tmp]# cat a.sh
#!/bin/bash
#
inotifywait -mrq -e delete,close_write,moved_to,moved_from,isdir /longshuai |
while read line;do
   if grep -i delete $line; then
       echo "At `date +"%F %T"`: $line" >>/etc/delete.log
   else
       rsync -az $line --password-file=/etc/rsync_back.passwd rsync://[email protected]::longshuai
   fi
done

1.2 inotifywait命令以及事件分析

inotifywait命令的选项:

-m:表示始终监控,否则应该是监控到了一次就退出监控了
-r:递归监控,监控目录中的任何文件,包括子目录。递归监控可能会超出max_user_watches的值,需要适当调整该值
@<file>:如果是对目录进行递归监控,则该选项用于排除递归目录中不被监控的文件。file是相对路径还是绝对路径由监控目录是相对还是绝对来决定
-q:--quiet的意思,静默监控,这样就不会输出一些无关的信息
-e:指定监控的事件。一般监控的就delete、create、attrib、modify、close_write
--exclude <pattern> :通过模式匹配来指定不被监控的文件,区分大小写
--excludei <pattern>:通过模式匹配来指定不被监控的文件,不区分大小写
--timefmt:监控到事件触发后,输出的时间格式,可指定可不指定该选项,一般设置为[--timefmt '%Y/%m/%d %H:%M:%S']
--format:用户自定义的输出格式,如[--format '%w%f %e%T']
  %w:产生事件的监控路径,不一定就是发生事件的具体文件,例如递归监控一个目录,该目录下的某文件产生事件,将输出该目录而非其内具体的文件
  %f:如果监控的是一个目录,则输出产生事件的具体文件名。其他所有情况都输出空字符串
  %e:产生的事件名称
  %T:以"--timefmt"定义的时间格式输出当前时间,要求同时定义"--timefmt"

inotifywait -e可监控的事件:

access:文件被访问
modify:文件被写入
attrib:元数据被修改。包括权限、时间戳、扩展属性等等
close_write:打开的文件被关闭,是为了写文件而打开文件,之后被关闭的事件
close_nowrite:read only模式下文件被关闭,即只能是为了读取而打开文件,读取结束后关闭文件的事件
close:是close_write和close_nowrite的结合,无论是何种方式打开文件,只要关闭都属于该事件
open:文件被打开
moved_to:向监控目录下移入了文件或目录,也可以是监控目录内部的移动
moved_from:将监控目录下文件或目录移动到其他地方,也可以是在监控目录内部的移动
move:是moved_to和moved_from的结合
moved_self:被监控的文件或目录发生了移动,移动结束后将不再监控此文件或目录
create:在被监控的目录中创建了文件或目录
delete:删除了被监控目录中的某文件或目录
delete_self:被监控的文件或目录被删除,删除之后不再监控此文件或目录
umount:挂载在被监控目录上的文件系统被umount,umount后不再监控此目录
isdir :监控目录相关操作

以下是几个示例:

[root@xuexi ~]# mkdir /longshuai

[root@xuexi ~]# inotifywait -m /longshuai   # 以前台方式监控目录,由于没指定监控的事件,所以监控所有事件
Setting up watches.
Watches established.

打开其他会话,对被监控目录进行一些操作,查看各操作会触发什么事件。

[root@xuexi ~]# cd  /longshuai    # 进入目录不触发任何事件

(1).向目录中创建文件,触发create、open attrib、close_write和close事件。

[root@xuexi longshuai]# touch a.log

/longshuai/ CREATE a.log
/longshuai/ OPEN a.log
/longshuai/ ATTRIB a.log
/longshuai/ CLOSE_WRITE,CLOSE a.log

如果是创建目录,则触发的事件则少的多。

[root@xuexi longshuai]# mkdir b

/longshuai/ CREATE,ISDIR b

ISDIR表示产生该事件的对象是一个目录。

(2).修改文件属性,触发attrib事件。

[root@xuexi longshuai]# chown 666 a.log

/longshuai/ ATTRIB a.log

(3).cat查看文件,触发open、access、close_nowrite和close事件。

[root@xuexi longshuai]# cat a.log

/longshuai/ OPEN a.log
/longshuai/ ACCESS a.log
/longshuai/ CLOSE_NOWRITE,CLOSE a.log

(4).向文件中追加或写入或清除数据,触发open、modify、close_write和close事件。

[root@xuexi longshuai]# echo "haha" >> a.log

/longshuai/ OPEN a.log
/longshuai/ MODIFY a.log
/longshuai/ CLOSE_WRITE,CLOSE a.log

(5).vim打开文件并修改文件,中间涉及到临时文件,所以有非常多的事件。

[root@xuexi longshuai]# vim a.log

/longshuai/ OPEN,ISDIR
/longshuai/ CLOSE_NOWRITE,CLOSE,ISDIR
/longshuai/ OPEN,ISDIR
/longshuai/ CLOSE_NOWRITE,CLOSE,ISDIR
/longshuai/ OPEN a.log
/longshuai/ CREATE .a.log.swp
/longshuai/ OPEN .a.log.swp
/longshuai/ CREATE .a.log.swx
/longshuai/ OPEN .a.log.swx
/longshuai/ CLOSE_WRITE,CLOSE .a.log.swx
/longshuai/ DELETE .a.log.swx
/longshuai/ CLOSE_WRITE,CLOSE .a.log.swp
/longshuai/ DELETE .a.log.swp
/longshuai/ CREATE .a.log.swp
/longshuai/ OPEN .a.log.swp
/longshuai/ MODIFY .a.log.swp
/longshuai/ ATTRIB .a.log.swp
/longshuai/ CLOSE_NOWRITE,CLOSE a.log
/longshuai/ OPEN a.log
/longshuai/ CLOSE_NOWRITE,CLOSE a.log
/longshuai/ MODIFY .a.log.swp
/longshuai/ CREATE 4913
/longshuai/ OPEN 4913
/longshuai/ ATTRIB 4913
/longshuai/ CLOSE_WRITE,CLOSE 4913
/longshuai/ DELETE 4913
/longshuai/ MOVED_FROM a.log
/longshuai/ MOVED_TO a.log~
/longshuai/ CREATE a.log
/longshuai/ OPEN a.log
/longshuai/ MODIFY a.log
/longshuai/ CLOSE_WRITE,CLOSE a.log
/longshuai/ ATTRIB a.log
/longshuai/ ATTRIB a.log
/longshuai/ MODIFY .a.log.swp
/longshuai/ DELETE a.log~
/longshuai/ CLOSE_WRITE,CLOSE .a.log.swp
/longshuai/ DELETE .a.log.swp

其中有"ISDIR"标识的是目录事件。此外,需要注意到vim过程中,相应的几个临时文件(.swp、.swx和以~为后缀的备份文件)也产生了事件,这些临时文件的相关事件在实际应用过程中,其实不应该被监控。

(6).向目录中拷入一个文件,触发create、open、modify和close_write、close事件。其实和新建文件基本类似。

[root@xuexi longshuai]# cp /bin/find .

/longshuai/ CREATE find
/longshuai/ OPEN find
/longshuai/ MODIFY find
/longshuai/ MODIFY find
/longshuai/ CLOSE_WRITE,CLOSE find

(7).向目录中移入和移除一个文件。

[root@xuexi longshuai]# mv /tmp/after.log /longshuai

/longshuai/ MOVED_TO after.log

[root@xuexi longshuai]# mv /longshuai/after.log /tmp

/longshuai/ MOVED_FROM after.log

(8).删除一个文件,触发delete事件。

[root@xuexi longshuai]# rm -f a.log

/longshuai/ DELETE a.log

从上面的测试结果中可以发现,很多动作都涉及了close事件,且大多数情况都是伴随着close_write事件的。所以,大多数情况下在定义监控事件时,其实并不真的需要监控open、modify、close事件。特别是close,只需监控它的分支事件close_write和close_nowrite即可。由于一般情况下inotify都是为了监控文件的增删改,不会监控它的访问,所以一般只需监控close_write即可。

由于很多时候定义触发事件后的操作都是根据文件来判断的,例如a文件被监控到了变化(不管是什么变化),就立即执行操作A,又由于对文件的一个操作行为往往会触发多个事件,例如cat查看文件就触发了open、access、close_nowrite和close事件,这样很可能会因为多个事件被触发而重复执行操作A。例如下面的示例,当监控到了/var/log/messages文件中出现了a.log关键字,就执行echo动作。

while inotifywait -mrq -e modify /var/log/messages; do
  if tail -n1 /var/log/messages | grep a.log; then
    echo "haha"
  fi
done

综合以上考虑,建议对监控对象的close_write、moved_to、moved_from、delete和isdir(主要是create,isdir,但无法定义这两个事件的整体,所以仅监控isdir)事件定义对应的操作,因为它们互不重复。如有需要,可以将它们分开定义,再添加需要监控的其他事件。例如:

[root@xuexi tmp]# cat a.sh
#!/bin/bash
#
inotifywait -mrq -e delete,close_write,moved_to,moved_from,isdir /longshuai |
while read line;do
   if grep -i delete $line; then
       echo "At `date +"%F %T"`: $line" >>/etc/delete.log
   else
       rsync -az $line --password-file=/etc/rsync_back.passwd rsync://rsync_backup@172.16.10.6::longshuai
   fi
done

1.3 inotify应该装在哪里

inotify是监控工具,监控目录或文件的变化,然后触发一系列的操作。

假如有一台站点发布服务器A,还有3台web服务器B/C/D,目的是让服务器A上存放站点的目录中有文件变化时,自动触发同步将它们推到web服务器上,这样能够让web服务器最快的获取到最新的文件。需要搞清楚的是,监控的是A上的目录,推送到的是B/C/D服务器,所以在站点发布服务器A上装好inotify工具。除此之外,一般还在web服务器BCD上将rsync配置为daemon运行模式,让其在873端口上处于监听状态。也就是说,对于rsync来说,监控端是rsync的客户端,其他的是rsync的服务端。

当然,这只是最可能的使用情况,并非一定需要如此。况且,inotify是独立的工具,它和rsync无关,它只是为rsync提供一种比较好的实时同步方式而已。

1.3 inotify应该装在哪里

inotify是监控工具,监控目录或文件的变化,然后触发一系列的操作。

假如有一台站点发布服务器A,还有3台web服务器B/C/D,目的是让服务器A上存放站点的目录中有文件变化时,自动触发同步将它们推到web服务器上,这样能够让web服务器最快的获取到最新的文件。需要搞清楚的是,监控的是A上的目录,推送到的是B/C/D服务器,所以在站点发布服务器A上装好inotify工具。除此之外,一般还在web服务器BCD上将rsync配置为daemon运行模式,让其在873端口上处于监听状态(并非必须,即使是sersync也非必须如此)。也就是说,对于rsync来说,监控端是rsync的客户端,其他的是rsync的服务端。

当然,这只是最可能的使用情况,并非一定需要如此。况且,inotify是独立的工具,它和rsync无关,它只是为rsync提供一种比较好的实时同步方式而已。

1.4 inotify+rsync示例脚本(不完善)

以下是监控/www目录的一个inotify+rsync脚本示例,也是网上流传的用法版本。但注意,该脚本非常烂,实际使用时需要做一些修改,此处仅仅只是示例(如果你不考虑资源消耗,那就无所谓)。

[[email protected] www]# cat ~/inotify.sh
#!/bin/bash

watch_dir=/www
push_to=172.16.10.5
inotifywait -mrq -e delete,close_write,moved_to,moved_from,isdir --timefmt '%Y-%m-%d %H:%M:%S' --format '%w%f:%e:%T' $watch_dir 
--exclude=".*.swp" |
while read line;do
  # logging some files which has been deleted and moved out
    if echo $line | grep -i -E "delete|moved_from";then
        echo "$line" >> /etc/inotify_away.log
    fi
  # from here, start rsync's function
    rsync -az --delete --exclude="*.swp" --exclude="*.swx" $watch_dir $push_to:/tmp
    if [ $? -eq 0 ];then
        echo "sent $watch_dir success"
    else
        echo "sent $watch_dir failed"
    fi
done

然后对上面的脚本赋予执行权限并执行。注意,该脚本是用来前台测试运行的,如果要后台运行,则将最后一段的if字句删掉。

该脚本记录了哪些被删除或从监控目录中移出的文件,且监控到事件后,触发的rsync操作是对整个监控目录$watch_dir进行同步,并且不对vim产生的临时文件进行同步。

前台运行该监控脚本。

[[email protected] www]# ~/inotify.sh

然后测试分别向监控目录/www下做拷贝文件、删除文件等操作。

例如删除文件,会先记录删除事件到/etc/inotify_away.log文件中,再执行rsync同步删除远端对应的文件。

/www/yum.repos.d/base.repo:DELETE:2017-07-21 14:47:46
sent /www success
/www/yum.repos.d:DELETE,ISDIR:2017-07-21 14:47:46
sent /www success

再例如,拷入目录/etc/pki到/www下,会产生多个rsync结果。

sent /www success
sent /www success
sent /www success
sent /www success
sent /www success
sent /www success
......

显然,由于拷入了多个文件,rsync被触发了多次,但其实rsync只要同步一次/www目录到远端就足够了,多余的rsync操作完全是浪费资源。如果拷入少量文件,其实无所谓,但如果拷入成千上万个文件,将长时间调用rsync。例如:

[[email protected] www]# cp -a /usr/share/man /www

拷入了15000多个文件到www目录下,该脚本将循环15000多次,且将调用15000多次rsync。虽然经过一次目录同步之后,rsync的性能消耗非常低(即使性能浪费少,但仍然是浪费),但它消耗大量时间时间资源以及网络带宽。

本文由金沙官网线上发布于操作系统,转载请注明出处:第2章 rsync(二):inotify+rsync详细说明和sersync,in

您可能还会对下面的文章感兴趣: