Inotify+Rsync实现linux文件实时同步
生活随笔
收集整理的這篇文章主要介紹了
Inotify+Rsync实现linux文件实时同步
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
公司一套系統(tǒng)的同步使用的donotify,不能實現(xiàn)子目錄的實時同步,通過查資料,發(fā)現(xiàn)inotify可以實現(xiàn)子目錄的實時同步,以下為筆記。 一、介紹 Inotify 是文件系統(tǒng)事件監(jiān)控機(jī)制,作為 dnotify 的有效替代。dnotify 是較早內(nèi)核支持的文件監(jiān)控機(jī)制。Inotify 是一種強(qiáng)大的、細(xì)粒度的、異步的機(jī)制,它滿足各種各樣的文件監(jiān)控需要,不僅限于安全和性能。 inotify 可以監(jiān)視的文件系統(tǒng)事件包括: IN_ACCESS,即文件被訪問 IN_MODIFY,文件被 write IN_ATTRIB,文件屬性被修改,如 chmod、chown、touch 等 IN_CLOSE_WRITE,可寫文件被 close IN_CLOSE_NOWRITE,不可寫文件被 close IN_OPEN,文件被 open IN_MOVED_FROM,文件被移走,如 mv IN_MOVED_TO,文件被移來,如 mv、cp IN_CREATE,創(chuàng)建新文件 IN_DELETE,文件被刪除,如 rm IN_DELETE_SELF,自刪除,即一個可執(zhí)行文件在執(zhí)行時刪除自己 IN_MOVE_SELF,自移動,即一個可執(zhí)行文件在執(zhí)行時移動自己 IN_UNMOUNT,宿主文件系統(tǒng)被 umount IN_CLOSE,文件被關(guān)閉,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) IN_MOVE,文件被移動,等同于(IN_MOVED_FROM | IN_MOVED_TO) 注:上面所說的文件也包括目錄。 二、為能在shell下使用inotify特性,需要安裝inotify-tools 1、inotify-tools:The general purpose of this package is to allow inotify's features to be used from within shell scripts. 下載地址:http://inotify-tools.sourceforge.net/ 編譯安裝 ./configure make make install 完成后,注意查看manpage,man inotify 、 man inotifywait 1)inotifywait 僅執(zhí)行阻塞,等待 inotify 事件。您可以監(jiān)控任何一組文件和目錄,或監(jiān)控整個目錄樹(目錄、子目錄、子目錄的子目錄等等)。在 shell 腳本中使用 inotifywait。 2)inotifywatch 收集關(guān)于被監(jiān)視的文件系統(tǒng)的統(tǒng)計數(shù)據(jù),包括每個 inotify 事件發(fā)生多少次。 2、inotify的系統(tǒng)相關(guān)參數(shù): /proc interfaces The following interfaces can be used to limit the amount of kernel memory consumed by inotify: /proc/sys/fs/inotify/max_queued_events The value in this file is used when an application calls inotify_init(2) to set an upper limit on the number of events that can be queued to the corresponding inotify instance. Events in excess of this limit are dropped, but an IN_Q_OVERFLOW event is always generated. /proc/sys/fs/inotify/max_user_instances This specifies an upper limit on the number of inotify instances that can be created per real user ID. /proc/sys/fs/inotify/max_user_watches This specifies a limit on the number of watches that can be associated with each inotify instance. 3、inotifywait 相關(guān)的參數(shù)(更多,查看manpage): inotifywait This command simply blocks for inotify events, making it appropriate for use in shell scripts. It can watch any set of files and directories, and can recursively watch entire directory trees. -m, --monitor Instead of exiting after receiving a single event, execute indefinitely. The default behaviour is to exit after the first event occurs. -r, --recursive Watch all subdirectories of any directories passed as arguments. Watches will be set up recursively to an unlimited depth. Symbolic links are not traversed. Newly created subdirectories will also be watched. -q, --quiet If specified once, the program will be less verbose. Specifically, it will not state when it has completed establishing all inotify watches. -e , --event Listen for specific event(s) only. The events which can be listened for are listed in the EVENTS section. This option can be specified more than once. If omitted, all events are listened for. use“,”separate multi events
? 三、使用 1.查看是否支持inotify,從kernel 2.6.13開始正式并入內(nèi)核,RHEL5已經(jīng)支持。看看是否有 /proc/sys/fs/inotify/目錄,以確定內(nèi)核是否支持inotify? [root@RHEL5 Rsync]# ll?/proc/sys/fs/inotify
total?0
-rw-r--r--?1?root root?0?Oct??9?09:36?max_queued_events
-rw-r--r--?1?root root?0?Oct??9?09:36?max_user_instances
-rw-r--r--?1?root root?0?Oct??9?09:36?max_user_watches 2.關(guān)于遞歸: inotifywait This command simply blocks for inotify events, making it appropriate for use in shell scripts. It can watch any set of files and directories, and can recursively watch entire directory trees. 3.使用: #!/bin/sh
src=/opt/webmail
des=/tmp
ip=192.168.7.192
/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
????????????????rsync?-avz?--delete?--progress ${src} root@${ip}:${des}?&&
????????????????echo?"${src} was rsynced"
????????????????echo?"---------------------------------------------------------------------------"
????????done 注:當(dāng)要排出同步某個目錄時,為rsync添加--exculde=PATTERN參數(shù),注意,路徑是相對路徑。詳細(xì)查看man rsync 當(dāng)要排除都某個目錄的事件監(jiān)控的處理時,為inotifywait添加--exclude或--excludei參數(shù)。詳細(xì)查看man inotifywait 另:/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' \ -e modify,delete,create,attrib \ ${src} \ 上面的命令返回的值類似于: 10/03/09 15:31 /wwwpic/1 這3個返回值做為參數(shù)傳給read,關(guān)于此處,有人是這樣寫的: inotifywait -mrq -e create,move,delete,modify $SRC | while read D E F;do細(xì)化了返回值。 注:要取得監(jiān)控文件發(fā)生的事件,在--format處指定%e參數(shù),同時,使用--event參數(shù)來指定要監(jiān)控的事件即可,如--format '%T %w%f %e' --event modify,delete,create,attrib 說明:當(dāng)文件系統(tǒng)發(fā)現(xiàn)指定目錄下有如上的條件的時候就觸發(fā)相應(yīng)的指令,是一種主動告之的而非我用循環(huán)比較目錄下的文件的異動,該程序在運行時,更改目錄內(nèi)的文件時系統(tǒng)內(nèi)核會發(fā)送一個信號,這個信號會觸發(fā)運行rsync命令,這時會同步源目錄和目標(biāo)目錄。 --timefmt:指定輸出時的輸出格式 --format: '%T %w%f'指定輸出的格式,上面的輸出類似于:12/10/08 06:34 /opt/webmail/dovecot-1.1.2/src/test/1 小腳本,同步到多臺主機(jī): 文件:
inotify_rsync.tar.gz
大小:
1KB
下載:
下載 更改后,更簡單,適用于同步到相同的目錄,監(jiān)控多目錄,多文件,同步到多臺服務(wù)器 #!/bin/sh
#set?-x
#var?
src="/usr/local/nginx/html/lib /usr/local/nginx/html/www /usr/local/nginx/html/var/www.work.com.conf.php"
des_ip="172.18.1.35 172.18.1.36 172.18.1.37 172.18.1.38"
#function
inotify_fun ()
{
/usr/local/bin/inotifywait?-mrq?--timefmt?'%d/%m/%y-%H:%M'?--format?'%T %w%f'?\
-e modify,delete,create,move $1|while?read time file
do?
for?ip in $des_ip
do
echo?"`date +%Y%m%d-%T`: rsync -avzq --delete --progress $1 $ip:`dirname $1`"
rsync?-avzq?--delete?--progress $1?$ip:`dirname $1`
echo
done
done
}
#main
for?a in $src
do
inotify_fun $a?&?
done 參考:http://www.ibm.com/developerworks/cn/linux/l-ubuntu-inotify/index.html
? 關(guān)于減少rsync的遍歷,未完:考慮到被監(jiān)測的目錄每次有一下時間時都會觸發(fā)rsync,modify, delete,create,move每次rsync都會遍歷源目錄,當(dāng)被監(jiān)測目錄內(nèi)文件特別多時,會造成系統(tǒng)資源的嚴(yán)重消耗,所以,讓rsync每次只同步修改的文件。因為,如果從監(jiān)控目錄mv走一個目錄,那么rsync只會報告找不到你移走的目錄而無法刪除備份機(jī)的應(yīng)該刪除的目錄。所以,對于刪除這個事件,沒有辦法了,只能同步被刪除文件或目錄的上級目錄了。將事件分為兩部分,modify, create, move事件,觸發(fā)rsync,只同步修改了的文件。delete事件,同步被刪除文件或目錄的上級目錄(不能越過要同步的根目錄)。 關(guān)于腳本內(nèi)容的一些說明: rsync.conf里的目錄格式一定要注意,沒有最后的“/" boot.sh 對于rsync命令的目標(biāo)地址,是由兩部分組成的: 1、rsync.conf里的dest des=`grep '^dest' ${basedir}/rsync.conf| cut -d '=' -f 2 ` 2、被修改了的文件的完全路徑,去掉源目錄部分,去掉被修改的文件的文件名。 mb=`echo $file|awk -F "/" '{NF=NF-1;OFS="/";print $0}'|sed "s#$src##g"` boot.sh ############################################################ 先做個記錄,腳本在delete部分還有問題 #!/bin/sh
#
basedir=/home/jason/Rsync
destNum=`grep?-c?'^dest'?${basedir}/rsync.conf`
src=`grep?'local directory='?${basedir}/rsync.conf|cut?-d?'='?-f?2`
des=`grep?'^dest'?${basedir}/rsync.conf|?cut?-d?'='?-f?2?`
#
inotifywait?-mrq?--timefmt?'%d/%m/%y %H:%M'?--format??'%T %w%f %e'?\
--event modify,create,move,delete??${src}?|?while?read??date time file event
????????do
????????????????echo $event
????????????for?i in $des
????????????do
????????????????case?$event in
????????????????MODIFY|CREATE|MOVE|MODIFY,ISDIR|CREATE,ISDIR|MODIFY,ISDIR)
????????????????????????#echo $src
????????????????????????no_src_root_file_name=`echo $file|sed?"s#$src##g"`
????????????????????????final_target_dest=$i$no_src_root_file_name
?????????????????????? echo rsync?-avz?--delete?--progress $file $final_target_dest
????????????????????????rsync?-avz?--delete?--progress $file $final_target_dest
????????????????;;
????????????????DELETE|DELETE,ISDIR)
????????????????????????src_file_up_dir=`echo $file|awk?-F"/"?'{NF=NF-1;OFS="/";print $0}'`
????????????????????????no_root_src_file_up_dir=`echo $file|awk?-F"/"?'{NF=NF-2;OFS="/";print $0}'|sed?"s#$src##g"`
????????????????????????final_target_dest_up_dir=$i$no_root_src_file_up_dir
????????????????echo????rsync?-avz?--delete?--progress $src_file_up_dir $final_target_dest_up_dir
????????????????????????rsync?-avz?--delete?--progress $src_file_up_dir $final_target_dest_up_dir
????????????????;;
????????????????esac
????????????done
????????done
############################################################################################
rsync.conf
local directory=/EBS/www/projects
#dest_here
dest=root@174.129.219.40:/EBS/www
20090723:
--format?'%T %w%f' 其中的%f參數(shù): %f When an event occurs within a directory, this will be replaced with the name of the File which caused he event to occur. Otherwise, this will be replaced with an empty string. 如果不加%f參數(shù),當(dāng)一個文件夾里的文件發(fā)生變化時,不會輸出文件名(需要自己echo腳本里read的變量),而時輸出發(fā)生變化的文件的文件夾名,可以將這一點用于減少rsync遍歷中的delete事件。 另外,%w是用于輸出發(fā)生變化的文件的。 %w This will be replaced with the name of the Watched file on which an event occurred.
? 三、使用 1.查看是否支持inotify,從kernel 2.6.13開始正式并入內(nèi)核,RHEL5已經(jīng)支持。看看是否有 /proc/sys/fs/inotify/目錄,以確定內(nèi)核是否支持inotify? [root@RHEL5 Rsync]# ll?/proc/sys/fs/inotify
total?0
-rw-r--r--?1?root root?0?Oct??9?09:36?max_queued_events
-rw-r--r--?1?root root?0?Oct??9?09:36?max_user_instances
-rw-r--r--?1?root root?0?Oct??9?09:36?max_user_watches 2.關(guān)于遞歸: inotifywait This command simply blocks for inotify events, making it appropriate for use in shell scripts. It can watch any set of files and directories, and can recursively watch entire directory trees. 3.使用: #!/bin/sh
src=/opt/webmail
des=/tmp
ip=192.168.7.192
/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
????????????????rsync?-avz?--delete?--progress ${src} root@${ip}:${des}?&&
????????????????echo?"${src} was rsynced"
????????????????echo?"---------------------------------------------------------------------------"
????????done 注:當(dāng)要排出同步某個目錄時,為rsync添加--exculde=PATTERN參數(shù),注意,路徑是相對路徑。詳細(xì)查看man rsync 當(dāng)要排除都某個目錄的事件監(jiān)控的處理時,為inotifywait添加--exclude或--excludei參數(shù)。詳細(xì)查看man inotifywait 另:/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' \ -e modify,delete,create,attrib \ ${src} \ 上面的命令返回的值類似于: 10/03/09 15:31 /wwwpic/1 這3個返回值做為參數(shù)傳給read,關(guān)于此處,有人是這樣寫的: inotifywait -mrq -e create,move,delete,modify $SRC | while read D E F;do細(xì)化了返回值。 注:要取得監(jiān)控文件發(fā)生的事件,在--format處指定%e參數(shù),同時,使用--event參數(shù)來指定要監(jiān)控的事件即可,如--format '%T %w%f %e' --event modify,delete,create,attrib 說明:當(dāng)文件系統(tǒng)發(fā)現(xiàn)指定目錄下有如上的條件的時候就觸發(fā)相應(yīng)的指令,是一種主動告之的而非我用循環(huán)比較目錄下的文件的異動,該程序在運行時,更改目錄內(nèi)的文件時系統(tǒng)內(nèi)核會發(fā)送一個信號,這個信號會觸發(fā)運行rsync命令,這時會同步源目錄和目標(biāo)目錄。 --timefmt:指定輸出時的輸出格式 --format: '%T %w%f'指定輸出的格式,上面的輸出類似于:12/10/08 06:34 /opt/webmail/dovecot-1.1.2/src/test/1 小腳本,同步到多臺主機(jī): 文件:
inotify_rsync.tar.gz
大小:
1KB
下載:
下載 更改后,更簡單,適用于同步到相同的目錄,監(jiān)控多目錄,多文件,同步到多臺服務(wù)器 #!/bin/sh
#set?-x
#var?
src="/usr/local/nginx/html/lib /usr/local/nginx/html/www /usr/local/nginx/html/var/www.work.com.conf.php"
des_ip="172.18.1.35 172.18.1.36 172.18.1.37 172.18.1.38"
#function
inotify_fun ()
{
/usr/local/bin/inotifywait?-mrq?--timefmt?'%d/%m/%y-%H:%M'?--format?'%T %w%f'?\
-e modify,delete,create,move $1|while?read time file
do?
for?ip in $des_ip
do
echo?"`date +%Y%m%d-%T`: rsync -avzq --delete --progress $1 $ip:`dirname $1`"
rsync?-avzq?--delete?--progress $1?$ip:`dirname $1`
echo
done
done
}
#main
for?a in $src
do
inotify_fun $a?&?
done 參考:http://www.ibm.com/developerworks/cn/linux/l-ubuntu-inotify/index.html
? 關(guān)于減少rsync的遍歷,未完:考慮到被監(jiān)測的目錄每次有一下時間時都會觸發(fā)rsync,modify, delete,create,move每次rsync都會遍歷源目錄,當(dāng)被監(jiān)測目錄內(nèi)文件特別多時,會造成系統(tǒng)資源的嚴(yán)重消耗,所以,讓rsync每次只同步修改的文件。因為,如果從監(jiān)控目錄mv走一個目錄,那么rsync只會報告找不到你移走的目錄而無法刪除備份機(jī)的應(yīng)該刪除的目錄。所以,對于刪除這個事件,沒有辦法了,只能同步被刪除文件或目錄的上級目錄了。將事件分為兩部分,modify, create, move事件,觸發(fā)rsync,只同步修改了的文件。delete事件,同步被刪除文件或目錄的上級目錄(不能越過要同步的根目錄)。 關(guān)于腳本內(nèi)容的一些說明: rsync.conf里的目錄格式一定要注意,沒有最后的“/" boot.sh 對于rsync命令的目標(biāo)地址,是由兩部分組成的: 1、rsync.conf里的dest des=`grep '^dest' ${basedir}/rsync.conf| cut -d '=' -f 2 ` 2、被修改了的文件的完全路徑,去掉源目錄部分,去掉被修改的文件的文件名。 mb=`echo $file|awk -F "/" '{NF=NF-1;OFS="/";print $0}'|sed "s#$src##g"` boot.sh ############################################################ 先做個記錄,腳本在delete部分還有問題 #!/bin/sh
#
basedir=/home/jason/Rsync
destNum=`grep?-c?'^dest'?${basedir}/rsync.conf`
src=`grep?'local directory='?${basedir}/rsync.conf|cut?-d?'='?-f?2`
des=`grep?'^dest'?${basedir}/rsync.conf|?cut?-d?'='?-f?2?`
#
inotifywait?-mrq?--timefmt?'%d/%m/%y %H:%M'?--format??'%T %w%f %e'?\
--event modify,create,move,delete??${src}?|?while?read??date time file event
????????do
????????????????echo $event
????????????for?i in $des
????????????do
????????????????case?$event in
????????????????MODIFY|CREATE|MOVE|MODIFY,ISDIR|CREATE,ISDIR|MODIFY,ISDIR)
????????????????????????#echo $src
????????????????????????no_src_root_file_name=`echo $file|sed?"s#$src##g"`
????????????????????????final_target_dest=$i$no_src_root_file_name
?????????????????????? echo rsync?-avz?--delete?--progress $file $final_target_dest
????????????????????????rsync?-avz?--delete?--progress $file $final_target_dest
????????????????;;
????????????????DELETE|DELETE,ISDIR)
????????????????????????src_file_up_dir=`echo $file|awk?-F"/"?'{NF=NF-1;OFS="/";print $0}'`
????????????????????????no_root_src_file_up_dir=`echo $file|awk?-F"/"?'{NF=NF-2;OFS="/";print $0}'|sed?"s#$src##g"`
????????????????????????final_target_dest_up_dir=$i$no_root_src_file_up_dir
????????????????echo????rsync?-avz?--delete?--progress $src_file_up_dir $final_target_dest_up_dir
????????????????????????rsync?-avz?--delete?--progress $src_file_up_dir $final_target_dest_up_dir
????????????????;;
????????????????esac
????????????done
????????done
############################################################################################
rsync.conf
local directory=/EBS/www/projects
#dest_here
dest=root@174.129.219.40:/EBS/www
20090723:
--format?'%T %w%f' 其中的%f參數(shù): %f When an event occurs within a directory, this will be replaced with the name of the File which caused he event to occur. Otherwise, this will be replaced with an empty string. 如果不加%f參數(shù),當(dāng)一個文件夾里的文件發(fā)生變化時,不會輸出文件名(需要自己echo腳本里read的變量),而時輸出發(fā)生變化的文件的文件夾名,可以將這一點用于減少rsync遍歷中的delete事件。 另外,%w是用于輸出發(fā)生變化的文件的。 %w This will be replaced with the name of the Watched file on which an event occurred.
轉(zhuǎn)載于:https://blog.51cto.com/make2008/370945
總結(jié)
以上是生活随笔為你收集整理的Inotify+Rsync实现linux文件实时同步的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: libsvm 数据预处理 模块化程序
- 下一篇: ibatis3 一对一搞定