原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。http://nolinux.blog.51cto.com/4824967/1433109
Sersync 項目利用 Inotify 和 Rsync 技術實現對服務器數據實時同步的解決方案,其中 Inotify 用于監控 Sersync 所在服務器上文件系統的事件變化,而 Rsync 是目前廣泛使用的本地以及異地數據同步工具,其優點是只對變化的目錄數據操作,甚至是一個文件不同的部分進行同步,所以其優勢大大超過使用掛接文件系統或 scp 等方式進行鏡像同步。
目前使用比較多的同步工具為 Inotify-tools 和 Openduckbill。Inotify-tools 在前面的博文介紹過,這里就不做闡述。簡單說下 Openduckbill,Openduckbill 也是 google 的一個開源項目,它也是依賴于inotif-tools,并且它 和 Inotify都是基于腳本語言編寫的,其設計思路同樣是采用文件系統事件監控機制 Inotify 與 Rsync 命令 來做設計架構的。這里在多說一點,有些朋友可能會在兩臺甚至多臺服務器之間,互相搭建 Inotify-tools + Rsync 之類的同步部署來做互相同步,這個是很不推薦的,主要一方面就是在同步的文件時間戳上容易出問題,導致同步失敗,甚至版本不同步。因此,如果你是要做互相同步,推薦使用 Csync 。
這里呢,就說說 Sersync 優于 Inotify-tools 和 Openduckbill 的地方吧!
1、Sersync 使用 c++ 編寫,對 linux 系統文件產生的臨時文件和重復的文件操作會進行過濾,在本文后面會提到該點。使用sersyc和rsync結合做同步的時候,會大大減少運行時所消耗的本地以及網絡資源,因此在速度方面有顯著提升。
2、相比 Inotify-tools 和 Openduckbill,Sersync 配置起來更為簡單方便。在谷歌 Sersync 項目下載的安裝包的 bin 目錄下,放置了已經編譯好的二進制文件,搭配 bin 目錄下的xml文件可以直接部署使用。
3、Sersync 采用多線程(默認10)進行同步(即可以并發同步多個不同文件),尤其是針對較大文件同步的時候,它能夠保證多個服務器實時保持同步狀態。
4、Sersync 自帶了出錯處理機制。它可以通過失敗隊列自動對之前出錯的文件進行重新同步操作。如果屆時依舊失敗,它會每 10 個小時對同步失敗的文件再進行重新同步操作,直到文件同步為止。
5、Sersync 自帶有 crontab 功能,因此不需要借助系統的 crontab ,只需在 xml 配置文件中開啟該功能,即可按預先的配置,每隔一段時間自動做一次整體同步操作。
6、Sersync 還自帶了 socket 與 refreshCDN 的協議擴展,可以滿足有特殊需求的公司二次開發。(之前的版本有http擴展,目前已去除)
下面是,Sersync 的設計結構圖:
以上是 Sersync 谷歌項目組上面的設計結構圖!現在可能是因為某些原因(你懂得),不能訪問谷歌的頁面,即使用某種方式出去也不能這個圖片也是打不開狀態了。本人之前珍藏的有,因此這里特把該圖貼出,方便大家學習。
鑒于,英文版本可能對廣大博友帶來閱讀壓力,下面特貼出中文翻譯過的版本。
針對上圖的設計架構,這里做幾點說明,來幫助大家閱讀和理解該圖:
1、線程組線程是等待線程隊列的守護線程,當事件隊列中有事件產生的時候,線程組守護線程就會逐個喚醒同步線程。當隊列中 Inotify 事件較多的時候,同步線程就會被全部喚醒一起工作。這樣設計的目的是為了能夠同時處理多個 Inotify 事件,從而提升服務器的并發同步能力。同步線程的最佳數量=核數 x 2 + 2。
那么之所以稱之為線程組線程,是因為每個線程在工作的時候,會根據服務器上新寫入文件的數量去建立子線程,子線程可以保證所有的文件與各個服務器同時同步。當要同步的文件較大的時候,這樣的設計可以保證每個遠程服務器都可以同時獲得需要同步的文件。
2、服務線程的作用有三個:
a、處理同步失敗的文件,將這些文件再次同步,對于再次同步失敗的文件會生成 rsync_fail_log.sh 腳本,記錄失敗的事件。
b、每隔10個小時執行 rsync_fail_log.sh 腳本一次,同時清空腳本。
c、crontab功能,可以每隔一定時間,將所有路徑整體同步一次。
3、過濾隊列的建立是為了過濾短時間內產生的重復的inotify信息,例如在刪除文件夾的時候,inotify就會同時產生刪除文件夾里的文件與刪除文件夾的事件,通過過濾隊列,當刪除文件夾事件產生的時候,會將之前加入隊列的刪除文件的事件全部過濾掉,這樣只產生一條刪除文件夾的事件,從而減輕了同步的負擔。同時對于修改文件的操作的時候,會產生臨時文件的重復操作。
Ifnotify事件分析
下面來用具體數據去做分析,來解釋為什么 Sersync 比 Inotify-tools 和 Openduckbill 更優秀!
首先來看一張圖,這張圖是從谷歌 Sersync 項目組的分析文檔里面摘出來的,該圖是對同一個文件做write and close操作的時候,產生的10個事件。
為什么我們認為腳本監控效率低?
由于我們執行復制,移動,新建,刪除等操作時,會產生諸多事件。又上圖來看他除了產生.開頭的隱藏臨時文件和~結尾的臨時文件,還產生了3個4913的數字命名的臨時文件(注意,在 write 文件的時候,總會產生這3個數字文件,除非write的文件名叫做4913時,才會產生別的數字命名的事件)。
因此當我們使用腳本監控,即使通過使用 –exclude 這樣的選項結合正則語法,也無法完美過濾掉一些文件系統產生的臨時文件和臨時事件,這樣就造成了 rsync 的反復執行。即便你把“.”開頭與“~”結尾的事件過濾了,對于test文件仍舊有3次操作,分別是8、64和256。
補充:這里簡單介紹下事件名稱與對應代碼。事件256代表create事件,事件8代表write_close事件,事件512代表remove事件,事件64是move_from事件,即將文件mv出當前路徑時產生事件。事件128是move_to事件,即將其它路徑的文件移入到當前路徑。移出與移入操作可以通過cookie值來確定是否是同一文件。由此可見,當移動操作時候,是將 test 移動為 test~ ,其實是修改了名字,通過 cookie 可以看出,它們是對同一文件的操作。
此時,我們 Sersync 的過濾隊列效果就出來了!
以下是過濾隊列的三大作用!
1、過濾隊列的第一個作用
按照如上的情形,如果通過過濾隊列,就只會剩下一個 8 號事件,一定程度上也提高了同步的效率。
2、過濾隊列的第二個作用
當你在本機刪除目錄的時候,假設你刪除了一個包含 5 個文件的目錄。Inotify 會產生 6 個事件出來,分別是 5 個文件刪除事件和 1 個目錄刪除事件。如果使用過濾隊列的話,正常情況下會只產生一個目錄刪除事件,這無疑大大減少了 Inotify 事件的產生,從而減少 Rsync 無謂的同步次數。當然,這里說的也不絕對。如果這 6 個事件分多次讀到進入隊列,那么可能還沒來得及過濾,就已經被同步線程從隊列中取走同步了,但是這確實在一定程度上減少了刪除目錄時的同步通信次數。
3、過濾隊列的第三個作用
它可以過濾監控目錄下的目錄。如果我們不想同步目錄下的某些目錄或者一些后綴的文件,只需要在inotify啟動的時候,remove 掉那些不需監控的子目錄監控即可。對于不需要監控的子目錄,產生的文件事件就會從載入同步隊列前過濾掉。如果使用 Rsync 用 -exclude 參數雖然也可以實現過濾,但是還要與 Rsync 守護進程進行了一次交互才行。
下面是一些關于 Inotfy識別事件和 Sersync 的資料博文,大家可以去看一看:
https://code.google.com/p/sersync
http://www.ibm.com/developerworks/cn/linux/l-inotifynew/
http://hi.baidu.com/johntech/item/282552cfe6edb735449416e3
轉自:http://nolinux.blog.51cto.com/4824967/1433109
原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/1972