本文首發於爛泥行天下。
上篇文章我們介紹瞭如何使用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 –y 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:輸出詳細信息。
@:排除不需要監視的文件,可以是相對路徑,也可以是絕對路徑。
–-fromfile:從文件讀取需要監視的文件或排除的文件,一個文件一行,排除的文件以@開頭。
-z:輸出表格的行和列,即使元素爲空。
–-exclude:正則匹配需要排除的文件,大小寫敏感。
–-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的集成已經全部配置完畢。