1、inotify簡介 php
inotify是Linux內核2.6.13 (June 18, 2005)版本新增的一個子系統(API),它提供了一種監控文件系統(基於inode的)事件的機制,能夠監控文件系統的變化如文件修改、新增、刪除等,並能夠將相應的事件通知給應用程序。該機制由著名的桌面搜索引擎項目beagle引入用於替代此前具備相似功能但存在諸多缺陷的dnotify。 html
inotify既能夠監控文件,也能夠監控目錄。當監控目錄時,它能夠同時監控目錄及目錄中的各子目錄及文件的。此外,inotify 使用文件描述符做爲接口,於是可使用一般的文件I/O操做select、poll和epoll來監視文件系統的變化。 node
inotify 能夠監視的文件系統常見事件包括: git
IN_ACCESS:文件被訪問 github
IN_MODIFY:文件被修改 web
IN_ATTRIB,文件屬性被修改 bash
IN_CLOSE_WRITE,以可寫方式打開的文件被關閉 服務器
IN_CLOSE_NOWRITE,以不可寫方式打開的文件被關閉 ssh
IN_OPEN,文件被打開 tcp
IN_MOVED_FROM,文件被移出監控的目錄
IN_MOVED_TO,文件被移入監控着的目錄
IN_CREATE,在監控的目錄中新建文件或子目錄
IN_DELETE,文件或目錄被刪除
IN_DELETE_SELF,自刪除,即一個可執行文件在執行時刪除本身
IN_MOVE_SELF,自移動,即一個可執行文件在執行時移動本身
經過/proc接口中的以下參數設定inotify可以使用的內存大小:
一、/proc/sys/fs/inotify/max_queue_events
應用程序調用inotify時須要初始化inotify實例,並時會爲其設定一個事件隊列,此文件中的值則是用於設定此隊列長度的上限;超出此上限的事件將會被丟棄;
二、/proc/sys/fs/inotify/max_user_instances
此文件中的數值用於設定每一個用戶ID(以ID標識的用戶)能夠建立的inotify實例數目的上限;
三、/proc/sys/fs/inotify/max_user_watches
此文件中的數值用於設定每一個用戶ID能夠監控的文件或目錄數目上限;
2、inotify-tools
inotify是一個API,須要經過開發應用程序進行調用,對於大多數用戶來說這有着許多不便,inotify-tools的出現彌補了這一不足。inotify-tools是一套組件,它包括一個C庫和幾個命令行工具,這些命令行工具可用於經過命令行或腳本對某文件系統的事件進行監控。它由Rohan McGovern開發,其項目網址爲http://inotify-tools.sourceforge.net。
inotify-tools提供的兩個命令行工具:
inotifywait:經過inotify API等待被監控文件上的相應事件並返回監控結果,默認狀況下,正常的結果返回至標準輸出,診斷類的信息則返回至標準錯誤輸出。它能夠在監控到對應監控對象上指定的事件後退出,也能夠進行持續性的監控。
inotifywatch:經過inotify API收集被監控文件或目錄的相關事件並輸出統計信息。
inotifywait命令使用簡介:
inotifywait尤爲適用於在腳本中等待某事件的發生,並可基於特定的事件執行相應操做。如將其用於腳本中監控某指定目錄中的文件上的修改、新建、刪除、屬性信息的改變,然後使用rsync命令將某事件對應的文件同步至其它主機上。其經常使用選項以下:
-m, --monitor:inotifywait的默認動做是在監控至指定文件的特定事件發生一次後就退出了,而使用此選項則可實現持續性的監控;
-r, --recursive:遞歸監控指定目錄下的全部文件,包括新建的文件或子目錄;若是要監控的目錄中文件數量巨大,則一般須要修改/proc/sys/fs/inotify/max_users_watchs內核參數,由於其默認值爲8192。
-e <event>, --event <event>:指定要監控的特定事件,默認是監控全部的事件;此處<event>包括access, modify, attrib, close_write, close_nowirte, close, open, moved_to, moved_from, move, create, delete, delete_selt等;
--timefmt <fmt>:當在--format選項中使用%T時,--timefrt選項則能夠用來指定自定義的符合strftime規範的時間格式,此時間格式可用的格式符能夠經過strftime的手冊頁獲取;--timefrt後經常使用的參數是'%d/%m/%y %H:%M';
--format <fmt>:自定義inotifywait的輸出格式,如--format '%T %w %f';經常使用的格式符以下:
%w:顯示被監控文件的文件名;
%f:若是發生某事件的對象是目錄,則顯示被監控目錄的名字;默認顯示爲空串;
%T:使用--timefmt選項中自定義的時間格式;
例如,要監控/tmp/test目錄及其內部全部文件上發生的create,delete,modify,close_write事件,則使用以下命令:
# inotify -r --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create,delete,modify,close_write /tmp/test
此命令在監控到某文件上第一次事件後就會退出,若是想一直監控,則須要爲命令添加-m選項。
在不少場景中都會用到將某主機上的某目錄下的全部文件改變實時同步至另外一主機上的指定位置,這也能夠經過在腳本中使用inotifywait結合rsync命令來實現,好比以下腳本:
#!/bin/bash
DESTHOST=172.16.100.6
DESTHOSTDIR=/www/htdocs/
SRCDIR=/www/htdocs/
inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \
-e create,delete,modify,attrib $SRCDIR | while read DATE TIME DIR FILE; do
$FILECHANGE=${DIR}${FILE}
rsync -avze 'ssh' $SRCDIR root@${DESTHOST}:${DESTHOSTDIR} &>/dev/null && \
echo "At ${TIME} on ${DATE}, file $FILECHANGE was backed up via rsync" >> /var/log/filesync.log
done
須要注意的是,此腳本中的rsync是經過ssh加密後進行文件傳輸的,所以須要事先配置好相應的ssh可以基於密鑰對用戶進行認證,以避免每一次文件同步都須要用戶手動輸入密碼。
固然,若是數據傳輸不須要加密,此處也能夠經過在目錄主機的啓動rsyncd守護進程來實現。
3、配置rsyncd+inotify實現文件實時同步:
本案例實現監控原主機上指定目錄中的全部文件變化,並將變化實時同步至目標主機的指定目錄中;所用主機及相關目錄以下:
源主機:RHEL5.4(x86),172.16.100.1, 文件所在的目錄爲/www/htdocs;
目標主機:RHEL5.4(x86),172.16.100.6, 文件所在的目錄爲/www/htdocs;
一、設定目標主機(本例爲172.16.100.6)
本案例中採用基於rsync守護進程的方式進行數據同步,其數據傳輸過程是明文方式,所以只適用於在特定的場景中應用。
1)安裝相關軟件:
目標主機是接收別的主機發送來的文件的服務器,所以,其rsync須要以守護進程的方式工做。rsync服務一般基於超級守護進程xinetd管理的方式來實現,所以須要事先安裝rysnc和xinetd:
# yum -y install rsync xinetd
2)爲rsync提供配置文件/etc/rsyncd.conf,內容相似以下內容:
# Section 1: Global settings
uid = nobody
gid = nobody
use chroot = no
max connections = 3
strict modes = yes
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
# Section 2:Directory to be synced
[htdocs]
path = /www/htdocs
ignore errors = yes
read only = no
write only = no
hosts allow = 172.16.0.0/16
hosts deny = *
list = false
uid = root
gid = root
auth users = wwwuser
secrets file = /etc/rsync.passwd
其中的相關指令及其說明能夠經過rsyncd.conf的手冊而獲取。而其訪問控制功能也可基於xinetd進行,具體方法請參照xinetd.conf的手冊頁。
3)提供secrets file所指定的口令文件/etc/rsync.passwd,其內容相似以下:
htdocsuser:passwOrdForhtdOcs
其中冒號前的是用戶名,冒號後的是對應用戶的密碼。此文件不能爲其餘任意用戶可訪問,所以可用以下命令修改:
# chmod 600 /etc/rsync.passwd
4)配置服務能夠開機啓動:
# chkconfig rsync on
# chkconfig xinetd on
# service xinetd start
默認狀況下,rsyncd監聽的端口爲873/TCP,這能夠經過以下命令查看:
# netstat -tnlp | grep ":873"
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 3653/xinetd
二、設定源主機
1)安裝相關軟件
源主機須要實時監控指定目錄中的全部文件上與文件改變相關的事件,並在事件發生時將改變的數據同步至目錄主機,所以,源主機上須要確保內核支持inotify,並安裝inotify-tools和rsync。
rsync的安裝參照目標主機的中的方式進行便可。
inotify-tools的安裝能夠基於源碼編譯的方式進行,也能夠經過安裝其rpm進行。
源碼下載地址:http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
rpm包下載頁面:http://rpm.pbone.net/index.php3/stat/4/idpl/15265939/dir/redhat_el_5/com/inotify-tools-3.14-1.el5.i386.rpm.html
這裏以編譯源代碼的方式演示安裝過程:
# tar xf inotify-tools-3.14.tar.gz
# cd inotify-tools-3.14
# ./configure
# make
# make install
# echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
# ldconfig
2)爲源主機的rsync提供經過htdocsuser用戶同步文件至目標主機的口令文件
# echo 'passwOrdForhtdOcs' > /etc/rsync.passwd
# chmod 600 /etc/rsync.passwd
注意,對於RHEL5.4自帶的2.6.8版本的rsync來講,其客戶端(即此處的源主機上的rsync)的口令文件中只能保存用戶的口令,而不能相似目標主機上可同時指定用戶名。
3)創建腳本/root/bin/htdocsync.sh,經過inotifywait監控目標文件上的相應事件,並在事件觸發時啓動同步過程:
#!/bin/bash
#
DESTHOST=172.16.100.6
DESTHOSTDIR=/www/htdocs/
SRCDIR=/www/htdocs/
inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e close_write,modify,delete,create,attrib $SRCDIR | while read DATE TIME DIR FILE; do
FILECHANGE=${DIR}${FILE}
rsync -avz --password-file=/etc/rsync.passwd $SRCDIR htdocsuser@${DESTHOST}::htdocs &>/dev/null && \
echo "At ${TIME} on ${DATE}, file $FILECHANGE was backed up via rsync" >> /var/log/websync.log
done
然後給此腳本執行權限,並執行便可:
# chmod u+x /root/bin/htdocsync.sh
# /root/bin/htdocsync.sh &
若是想讓此功能能夠在開機時自動啓動,則能夠經過以下方式進行:
# echo '/root/bin/htdocsync.sh &' >> /etc/rc.d/rc.local
補充說明:若是您指望將源主機上的數據同步至多臺目標主機,對每一個目標主機均相似上面的目標主機的設定方法進行設定便可。