http://code.google.com/p/sersync/
本文最新地址:http://blog./technology/115
項(xiàng)目簡介:
本項(xiàng)目利用inotify與rsync對(duì)服務(wù)器進(jìn)行實(shí)時(shí)同步,其中inotify用于監(jiān)控文件系統(tǒng)事件,rsync是目前廣泛使用的同步算法,其優(yōu)點(diǎn)是只對(duì)文件不同的部分進(jìn)行操作,所以其優(yōu)勢大大超過使用掛接文件系統(tǒng)的方式進(jìn)行鏡像同步。
目前使用的比較多的同步程序版本是inotify-tools,另外一個(gè)是google開源項(xiàng)目Openduckbill(依賴于inotify-tools),這兩個(gè)都是基于腳本語言編寫的,其設(shè)計(jì)思路同樣是采用inotify與rsync命令。 相比較上面兩個(gè)項(xiàng)目,本項(xiàng)目優(yōu)點(diǎn)是:
1.sersync是使用c++編寫,而且對(duì)linux系統(tǒng)文件系統(tǒng)產(chǎn)生的臨時(shí)文件和重復(fù)的文件操作進(jìn)行過濾(我稍后會(huì)提到),所以在結(jié)合rsync同步的時(shí)候,節(jié)省了運(yùn)行時(shí)耗和網(wǎng)絡(luò)資源。因此更快。
2.相比較上面兩個(gè)項(xiàng)目,sersync配置起來很簡單:在http://code.google.com/p/sersync/downloads/list 處下載源碼(分為32版本,與64位版本),其中bin目錄下已經(jīng)有我編譯好的2進(jìn)制文件,配合bin目錄下的xml文件直接使用即可。
3.另外本項(xiàng)目相比較其他腳本開源項(xiàng)目,使用多線程進(jìn)行同步,尤其在同步較大文件時(shí),能夠保證多個(gè)服務(wù)器實(shí)時(shí)保持同步狀態(tài)。
4.本項(xiàng)目自帶出錯(cuò)處理機(jī)制,通過失敗隊(duì)列對(duì)出錯(cuò)的文件重新出錯(cuò),如果仍舊失敗,則每10個(gè)小時(shí)對(duì)同步失敗的文件重新同步。
5.本項(xiàng)目自帶crontab功能,只需在xml配置文件中開啟,即可按您的要求,隔一段時(shí)間整體同步一次。
6.本項(xiàng)目自帶socket與http協(xié)議擴(kuò)展,滿足您二次開發(fā)的需要。
基本架構(gòu):

設(shè)計(jì)簡析 如上圖所示,線程組線程是等待線程隊(duì)列的守護(hù)線程,當(dāng)隊(duì)列中有數(shù)據(jù)的時(shí)候,線程組守護(hù)線程逐個(gè)喚醒,當(dāng)隊(duì)列中inotify事件交多的時(shí)候就會(huì)被全部喚醒一起工作。這樣設(shè)計(jì)的目的是能夠同時(shí)處理多個(gè)inotify事件,重發(fā)利用服務(wù)器的并發(fā)能力(核數(shù)*2+2)。
之所以稱之為線程組線程,是因?yàn)槊總€(gè)線程在工作的時(shí)候,會(huì)根據(jù)服務(wù)器的數(shù)量建立子線程,子線程可以保證所有的文件與各個(gè)服務(wù)器同時(shí)同步,當(dāng)要同步的文件較大的時(shí)候,這樣設(shè)計(jì)可以保證各個(gè)遠(yuǎn)程服務(wù)器可以同時(shí)獲得要同步的文件。
服務(wù)線程的作用有三個(gè),首先是處理同步失敗的文件,將這些文件再次同步,對(duì)于再次同步失敗的文件會(huì)生成rsync_fail_log.sh腳本,記錄失敗的事件。同時(shí)每隔10個(gè)小時(shí)執(zhí)行腳本一次,同時(shí)清空腳本。服務(wù)線程的第三個(gè)作用是crontab功能,可以每隔一定時(shí)間,將所有路徑整體同步一次。
過濾隊(duì)列的建立是為了過濾短時(shí)間內(nèi)產(chǎn)生的重復(fù)的inotify信息,例如在刪除文件夾得時(shí)候,inotify就會(huì)同時(shí)產(chǎn)生刪除文件夾里的文件與刪除文件夾得事件,通過過濾隊(duì)列當(dāng)刪除文件夾事件產(chǎn)生的時(shí)候,會(huì)將之前加入隊(duì)列的刪除文件的事件全部過濾掉,這樣只產(chǎn)生一條事件減輕了同步的負(fù)擔(dān)。同時(shí)對(duì)于修改文件的操作的時(shí)候,會(huì)產(chǎn)生臨時(shí)文件與重復(fù)操作。
舉例:
當(dāng)我們在vi的一個(gè)test文件,進(jìn)行wq操作的時(shí)候會(huì)產(chǎn)生如下事件:

即使把"."開頭與"~"結(jié)尾的世界過濾了,對(duì)于test文件仍舊有3次操作,分別是刪除,創(chuàng)建與保存,通過過濾隊(duì)列,就只剩下一個(gè)事件,一定程度上也提高了效率。
過濾隊(duì)列第二個(gè)作用,即當(dāng)你在本機(jī)刪除目錄的時(shí)候,假設(shè)你刪除一個(gè)有5個(gè)文件的目錄,inotify會(huì)產(chǎn)生6個(gè)事件,分別是5個(gè)文件刪除事件,和一個(gè)刪除目錄事件,如果使用過濾隊(duì)列,正常情況下會(huì)只產(chǎn)生一個(gè)刪除目錄的事件,大大減少了rsync通信次數(shù)。(當(dāng)然,這不是絕對(duì)的。如果這6個(gè)事件分多次讀到進(jìn)入隊(duì)列,那么可能還沒來得及過濾,就已經(jīng)被同步線程從隊(duì)列中取走同步了。但一定程度上可以減少刪除文件夾得同步通信次數(shù))。
過濾隊(duì)列的第三個(gè)作用,可以過濾監(jiān)控目錄下的文件夾,如果不想同步目錄下的一些文件夾,或者一些后綴的文件。對(duì)于不需監(jiān)控的子文件夾,在inotify啟動(dòng)時(shí)候remove掉監(jiān)控,對(duì)于不需監(jiān)控子文件,產(chǎn)生的文件事件就會(huì)從在入同步隊(duì)列前過濾掉。如果使用rsync用--exclude, 這樣雖然也可以過濾,但還是與rsync守護(hù)進(jìn)程進(jìn)行了一次交互。
關(guān)于inotify識(shí)別事件,詳見我上一篇博客:
http://hi.baidu.com/johntech/blog/item/e4a31a3db1ee1ce755e723f4.html