rsync and inotify

inotify 簡介

是一個內核用於通知用戶空間程序文件系統變化的機制,是一種強大的、細顆粒的、異步的文件系統監控機制,內核從2.6.13起,加入Inotify能夠監控文件系統中添加、刪除、修改移動等各類事件,利用這個內核接口,就能夠監控文件系統下文件的各類變化狀況。linux

安裝

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum -y install inotify-toolsweb

一共安裝了2個工具,即inotifywait和inotifywatch
inotifywait:在被監控的文件或目錄上等待特定文件系統事件(open,close,delete等)發生,執行後處於阻塞狀態,適合shell腳本中使用。
inotifywatch:收集被監視的文件系統使用度統計數據,指文件系統事件發生的次數統計。shell

語法格式

inotifywait  -mrq  --format '%Xe %w%f' -e modify,create,delete,attrib /data/bash

執行上面命令,是讓inotifywait監聽/data/目錄,當監聽到有發生modify,create,delete,attrib等事件發生時,按%Xe %w%f的格式輸出。less

inotifywait 參數說明

參數名稱 參數說明
-m,–monitor 始終保持事件監聽狀態
-r,–recursive 遞歸查詢目錄
-q,–quiet 只打印監控事件的信息
–excludei 排除文件或目錄時,不區分大小寫
-t,–timeout 超時時間
–timefmt 指定時間輸出格式
–format 指定時間輸出格式
-e,–event 後面指定刪、增、改等事件
 

-e :--event的各類事件含義

access		文件或目錄被讀取

modify		文件被改動(不涉及目錄),有如下幾種請況
	1.vi 文件(不管存在與否)未做更改,顯示爲*.swp
	  vi 文件作更改,wq退出,顯示爲file/file.swp	  	
	2.command >>或> file,不管file 存在與否
	
attrib		文件或目錄屬性(時間戳、屬組/主,其餘拓展屬性)被改變,遞歸改變目錄屬性時那麼全部子目錄也會列出。注意touch 文件也會監控到
	1.chown root:root  /opt/  -R		把全部的被改變屬性目錄所有列出,文件表示爲:「ATTRIB」 ,目錄標識爲:「ATTRIBXISDIR」

close_write   監控文件以能夠寫入的模式被打開的文件「被關閉」的事件
	1.vi 與modify 相似,有swp或swpx 產生
	2.command >>/> 與modify 相似

close_nowrite  監控文件被以只讀的模式打開後的關閉事件(打開文件以前打開的目錄也會記錄)
	cat/less/more	目錄標識爲:「CLOSE_NOWRITEXCLOSEXISDIR」	 文件標識爲:CLOSE_NOWRITEXCLOSE

close		包括 close_write and close_nowrite

open		打開文件事件,與close 正好相反

moved_to	被監控的目錄內的目錄或文件被更名(位置不變),其餘位置的文件/目錄被移動到被監控的目錄內
			文件標識爲:MOVED_TO  目錄標識爲:MOVED_TOXISDIR

moved_from	被監控的目錄內的目錄或文件被更名(位置不變),被監控的目錄內目錄/文件被移動到其餘位置

move		both  moved_to and moved_from
	
move_self	監控事件爲:被監控的目錄/文件自己被更名/移動,注意文件/目錄被改動後,也就沒法監控了

create		文件/目錄被建立,vi 即便不保存也會生成swp 輸出 
			CREATE/CREATEXISDIR
delete		文件/目錄被刪除,vi編輯時也會發生刪除swp,swxp 文件的事件
			DELETE
			
delete_self	刪除監控的文件/目錄自己的事件,注意只是自己而不是子目錄或文件,可是刪除的自己目錄若是有子目錄一併輸出;一旦被刪除,即便再建立再刪除也不會再監控此事件,
			除非建立後從新開啓監控命令。
			DELETE_SELF
			DELETE_SELF /opt/local/dir11/dir2/dir3/dir4/dir5/
			DELETE_SELF /opt/local/dir11/dir2/dir3/dir4/
			DELETE_SELF /opt/local/dir11/dir2/dir3/
			DELETE_SELF /opt/local/dir11/dir2/
			DELETE_SELF /opt/local/dir11/
			DELETE_SELF /opt/local/

unmount		監控被監控的目錄被卸載事件,注意目錄被卸載後,事件對象顯示被卸載目錄包括了監控目錄的各個子目錄;
			一旦被卸載便可再掛載也不會再監控此事件了,觸發先掛載前提下再從新監控目錄
			UNMOUNT /mnt/repodata/
			UNMOUNT /mnt/Packages/
			UNMOUNT /mnt/isolinux/
			UNMOUNT /mnt/images/pxeboot/
			UNMOUNT /mnt/images/
			UNMOUNT /mnt/EFI/BOOT/
			UNMOUNT /mnt/EFI/
			UNMOUNT /mnt/
View Code

inotifywait + rsync

用inotify+rsync作實時同步達到分佈式系統配置的一致性的目的異步

網上常見的腳本

#!/bin/bash
/usr/bin/inotifywait -mrq --format '%w%f'-e create,close_write,delete /backup |while read file
#把發生更改的文件列表都接收到file 而後循環,下面的命令都沒有引用這個$file 下面作的是全量rsync
do
    cd /backup && rsync -az --delete /backup/ rsync_backup@192.168.1.101::backup/--password-file=/etc/rsync.password
done

上述腳本,在監控的目錄文件很大的請況下同步效率很低,沒法作到實時性。緣由是inotifywait 監控到的任何在backup目錄下的特定事件都會觸發管道後while內的rsync操做,rsync 分佈式

掃描的是/bakcup 的整個目錄根據文件變化同步,而不是隻掃描同步發生變化的字目錄/文件。ide

改良後的版本

#!/bin/bash
rsync_passwd_file=/etc/rsync2.pass
ip1=192.168.1.101
user=root 
src=/data/
des=test
cd ${src}                                                #因爲rsync -R參數同步的特性,這裏必需要先cd到源目錄,inotify再監聽 ./ 才能rsync同步後目錄結構一致

/usr/local/inotify/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move  ./  | while read file
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify輸出切割 把事件類型部分賦值給INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify輸出切割 把文件路徑部分賦值給INO_FILE
        
    #增長、修改、寫入完成、移動進事件。增、改放在同一個判斷,由於他們都確定是針對文件的操做,即便是新建目錄,要同步的也只是一個空目錄,不會影響速度。    
    if [[ $INO_EVENT =~ 'CREATE' ]]||[[ $INO_EVENT =~ 'MODIFY' ]]||[[ $INO_EVENT =~ 'CLOSE_WRITE' ]]||[[ $INO_EVENT =~ 'MOVED_TO' ]]&&[[ ! $INO_FILE =~ '.swp' ]];then         # 判斷事件類型
        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}  --exclude='services/*/logs'      
        # -c校驗文件內容,-R參數把源的目錄結構遞歸到目標後面保證目錄結構一致性,注意-R只同步源文件和源文件所在的絕對路徑的目錄結構,不一樣步目錄內的其餘文件
        #上面的rsync同步命令 源是用了$(dirname ${INO_FILE})變量即每次只針對性的同步發生改變的文件的目錄(只同步目標文件的方法在生產環境的某些極端環境下會漏文件如今能夠在不漏文件下也有不錯的速度作到平衡)
                
    elif [[ $INO_EVENT =~ 'DELETE' ]]||[[ $INO_EVENT =~ 'MOVED_FROM' ]];then
        rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} --exclude='services/*/logs' 
        #若是直接同步已刪除的路徑${INO_FILE}會報no such or directory錯誤因此這裏同步的源是被刪文件或目錄的上一級路徑,並加上--delete來刪除目標上有而源中沒有的文件,這裏不能作到指定文件刪除,若是刪除的路徑越靠近根,則同步的目錄越多,同步刪除的操做就越花時間。                    
                    
    elif [[ $INO_EVENT =~ 'ATTRIB' ]]&&[ ! -d "$INO_FILE" ]&&[[ ! $INO_FILE =~ '.swp' ]];then    
    # 若是修改屬性的是目錄 則不一樣步,由於同步目錄會發生遞歸掃描,等此目錄下的文件發生同步時,rsync會順帶更新此目錄。    
        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} --exclude='services/*/logs'
done
View Code

每兩小時作1次全量同步

由於inotify只在啓動時會監控目錄,他沒有啓動期間的文件發生更改,他是不知道的,因此這裏每2個小時作1次全量同步,防止各類意外遺漏,保證目錄一致。工具

crontab  -e
* * /2  * * *  rsync  -avz --password- file = /etc/rsync-client .pass  /data/      root@192.168.1.101::data

說明:

1.爲了提升同步效率,只針對發生變化的目錄/文件的上一級目錄進行同步,此處使用了dirname優化

 rsync -avzcR --password-file=${rsync_passwd_file}   $(dirname ${INO_FILE})   ${user}@${ip1}::test

2.-R 參數的目的是同步發生變化的文件和文件的目錄結構。例如監控的/data 目錄,操做touch  /data/test/a.txt ,  使用了dirname 獲得的是不帶後綴「/」的目錄/data/test ,因此同步的       是  test整個目錄,可是-R 參數表示會同步新建文件a.txt 以及a.txt 的絕對路徑的目錄結構/data/test ,注意只同步目錄結構不會同步/data/test/內的其餘子文件和目錄。 因此此時出     現了一個問題就是會把整個data 目錄同步到對端的目錄下,即在對端目錄下建立整個data目錄,而咱們的初衷是data 和對端目錄兩個目錄之間數據同步,此時經過cd 監控目錄,再     inotifywait ./目錄,再發生變化後dirname 後獲得的路徑就是 ./../.. 結構,-R參數同步的就是當前目錄下的絕對路徑了。

3.因爲rsync -R參數同步的特性,這裏必需要先cd到源目錄,inotify再監聽 ./ 才能rsync同步後目錄結構一致,詳見2說明

   cd ${src} /usr/local/inotify/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move  ./  | while read file

4. 關於 .swp 是vi 命令時產生的臨時的交換文件,此文件產生時沒必要同步,因此要排除。

5.設計到日誌等文件時不須要同步,此時使用了  --exclude='services/*/logs' ,排除了./services/*/logs目錄的同步,注意此處使用了通配符 「*」,另外須要注意的是須要刪除時,使用的     是--delete  ,同時使用delete exclude 那麼排除的文件不會 被delete 刪除。

inotify 優化

# 在/proc/sys/fs/inotify目錄下有三個文件,對inotify機制有必定的限制

[root@web ~]# ll /proc/sys/fs/inotify/

總用量0

-rw-r--r--1 root root 09月923:36 max_queued_events

-rw-r--r--1 root root 09月923:36 max_user_instances

-rw-r--r--1 root root 09月923:36 max_user_watches

參數含義

max_user_watches       #設置inotifywait或inotifywatch命令能夠監視的文件數量(單進程)

max_user_instances     #設置每一個用戶能夠運行的inotifywait或inotifywatch命令的進程數

max_queued_events     #設置inotify實例事件(event)隊列可容納的事件數量

臨時生效(能夠改配置文件永久生效)

echo 50000000>/proc/sys/fs/inotify/max_user_watches -- 把他加入/etc/rc.local就能夠實現每次重啓都生效

echo 50000000>/proc/sys/fs/inotify/max_queued_events

相關文章
相關標籤/搜索