最近一直在尋求生産服務伺服器上的同步替代方案,原先使用的是<code>inotify + rsync</code>,但随着檔案數量的增大到100w+,目錄下的檔案清單就達20m,在網絡狀況不佳或者限速的情況下,變更的檔案可能10來個才幾m,卻是以要發送的檔案清單就達20m,嚴重減低的帶寬的使用效率以及同步效率;更為要緊的是,加入inotifywait在5s内監控到10個小檔案發生變化,便會觸發10個rsync同步操作,結果就是真正需要傳輸的才2-3m的檔案,比對的檔案清單就達200m。使用這兩個組合的好處在于,它們都是最基本的軟體,可以通過不同選項做到很精确的控制,比如排除同步的目錄,同步多個子產品或同步到多個主機。
國産開源,文檔不是很全,在2011年之後就沒更新了(googlecode都要快關閉了,其實可以轉交其他人維護),網上關于它的使用和讨論都止于10年了
采用xml配置檔案的方式,可讀性比較好,但是有些原生的有些功能沒有實作就沒法使用了
無法實作多目錄同步,隻能通過多個配置檔案啟動多個程序
檔案排除功能太弱。這個要看需求,不是每個人都需要排除子目錄。而對于我的環境中,這個功能很重要,而且排除的規則較多
雖然提供插件的功能,但很雞肋,因為軟體本身沒有持續更新,也沒有看到貢獻有其它插件出現(可能是我知識面不夠,還用不到裡面的refreshcdn plugin)。
其實我們也不能要求每一個軟體功能都十分健全,關鍵是看能否滿足我們當下的特定的需求。所謂好的架構不是設計出來的,而是進化來的。目前使用<code>sersync2</code>沒什麼問題,而且看了它的設計思路應該是比較科學的,特别是過濾隊列的設計。雙向同步看起來也是可以實作。
lysncd 實際上是lua語言封裝了 inotify 和 rsync 工具,采用了 linux 核心(2.6.13 及以後)裡的 inotify 觸發機制,然後通過rsync去差異同步,達到實時的效果。我認為它最令人稱道的特性是,完美解決了 <code>inotify + rsync</code>海量檔案同步帶來的檔案頻繁發送檔案清單的問題 —— 通過時間延遲或累計觸發事件次數實作。另外,它的配置方式很簡單,lua本身就是一種配置語言,可讀性非常強。lsyncd也有多種工作模式可以選擇,本地目錄cp,本地目錄rsync,遠端目錄rsyncssh。
實作簡單高效的本地目錄同步備份(網絡存儲挂載也當作本地目錄),一個指令搞定。
這一節實作的功能是,本地目錄source實時同步到另一個目錄target,而在source下有大量的檔案,并且有部分目錄和臨時檔案不需要同步。
安裝<code>lsyncd</code>極為簡單,已經收錄在ubuntu的官方鏡像源裡,直接通過<code>apt-get install lsyncd</code>就可以。
源碼編譯安裝
從源碼編譯安裝可以使用最新版的lsyncd程式,但必須要相應的依賴庫檔案和編譯工具:<code>yum install lua lua-devel asciidoc cmake</code>。
我這個版本編譯時有個小bug,如果按照<code>install</code>在<code>build</code>目錄中make,會提示:
解決辦法是要麼直接在解壓目錄下cmake,不要<code>mkdir build</code>,要麼在<code>cmakelist.txt</code>中搜尋<code>doc</code>字元串,在前面加上<code>${project_source_dir}</code>。
下面都是在編譯安裝的情況下操作。
到這啟動 lsycnd 就可以完成實時同步了,預設的許多參數可以滿足絕大部分需求,非常簡單。
settings
裡面是全局設定,<code>--</code>開頭表示注釋,下面是幾個常用選項說明:
<code>logfile</code> 定義日志檔案
<code>stausfile</code> 定義狀态檔案
<code>nodaemon=true</code> 表示不啟用守護模式,預設
<code>statusinterval</code> 将lsyncd的狀态寫入上面的statusfile的間隔,預設10秒
<code>inotifymode</code> 指定inotify監控的事件,預設是<code>closewrite</code>,還可以是<code>modify</code>或<code>closewrite or modify</code>
<code>maxprocesses</code> 同步程序的最大個數。假如同時有20個檔案需要同步,而<code>maxprocesses = 8</code>,則最大能看到有8個rysnc程序
<code>maxdelays</code> 累計到多少所監控的事件激活一次同步,即使後面的<code>delay</code>延遲時間還未到
sync
裡面是定義同步參數,可以繼續使用<code>maxdelays</code>來重寫settings的全局變量。一般第一個參數指定<code>lsyncd</code>以什麼模式運作:<code>rsync</code>、<code>rsyncssh</code>、<code>direct</code>三種模式:
<code>default.rsync</code> :本地目錄間同步,使用rsync,也可以達到使用ssh形式的遠端rsync效果,或daemon方式連接配接遠端rsyncd程序;
<code>default.direct</code> :本地目錄間同步,使用<code>cp</code>、<code>rm</code>等指令完成差異檔案備份;
<code>default.rsyncssh</code> :同步到遠端主機目錄,rsync的ssh模式,需要使用key來認證
<code>source</code> 同步的源目錄,使用絕對路徑。
<code>target</code> 定義目的位址.對應不同的模式有幾種寫法:
<code>/tmp/dest</code> :本地目錄同步,可用于<code>direct</code>和<code>rsync</code>模式
<code>172.29.88.223:/tmp/dest</code> :同步到遠端伺服器目錄,可用于<code>rsync</code>和<code>rsyncssh</code>模式,拼接的指令類似于<code>/usr/bin/rsync -ltsd --delete --include-from=- --exclude=* source target</code>,剩下的就是rsync的内容了,比如指定username,免密碼同步
<code>172.29.88.223::module</code> :同步到遠端伺服器目錄,用于<code>rsync</code>模式
三種模式的示例會在後面給出。
<code>init</code> 這是一個優化選項,當<code>init = false</code>,隻同步程序啟動以後發生改動事件的檔案,原有的目錄即使有差異也不會同步。預設是<code>true</code>
<code>delay</code> 累計事件,等待rsync同步延時時間,預設15秒(最大累計到1000個不可合并的事件)。也就是15s内監控目錄下發生的改動,會累積到一次rsync同步,避免過于頻繁的同步。(可合并的意思是,15s内兩次修改了同一檔案,最後隻同步最新的檔案)
<code>excludefrom</code> 排除選項,後面指定排除的清單檔案,如<code>excludefrom = "/etc/lsyncd.exclude"</code>,如果是簡單的排除,可以使用<code>exclude = list</code>。
這裡的排除規則寫法與原生rsync有點不同,更為簡單:
監控路徑裡的任何部分比對到一個文本,都會被排除,例如<code>/bin/foo/bar</code>可以比對規則<code>foo</code>
如果規則以斜線<code>/</code>開頭,則從頭開始要比對全部
如果規則以<code>/</code>結尾,則要比對監控路徑的末尾
<code>?</code>比對任何字元,但不包括<code>/</code>
<code>*</code>比對0或多個字元,但不包括<code>/</code>
<code>**</code>比對0或多個字元,可以是<code>/</code>
rsync
(提示一下,<code>delete</code>和<code>exclude</code>本來都是rsync的選項,上面是配置在sync中的,我想這樣做的原因是為了減少rsync的開銷)
<code>bwlimit</code> 限速,機關kb/s,與rsync相同(這麼重要的選項在文檔裡竟然沒有标出)
<code>compress</code> 壓縮傳輸預設為<code>true</code>。在帶寬與cpu負載之間權衡,本地目錄同步可以考慮把它設為<code>false</code>
<code>perms</code> 預設保留檔案權限。
其它rsync的選項
其它還有rsyncssh模式獨有的配置項,如<code>host</code>、<code>targetdir</code>、<code>rsync_path</code>、<code>password_file</code>,見後文示例。<code>rsyncops={"-avz","--delete"}</code>這樣的寫法在2.1.*版本已經不支援。
<code>lsyncd.conf</code>可以有多個<code>sync</code>,各自的source,各自的target,各自的模式,互不影響。
使用指令加載配置檔案,啟動守護程序,自動同步目錄操作。
以下配置本人都已經過驗證可行,必須根據實際需要裁剪配置:
上面的内容幾乎涵蓋了所有同步的模式,其中第<code>iii</code>個要求像rsync一樣配置rsyncd服務端,見本文開頭。第<code>iv</code>、<code>v</code>配置ssh方式同步,達到的效果相同,但實際同步時你會發現每次同步都會提示輸入ssh的密碼,可以通過以下方法解決:
在遠端被同步的伺服器上開啟ssh無密碼登入,請注意使用者身份:
把<code>id_rsa</code>私鑰拷貝到執行lsyncd的機器上
另外偶然想到個問題,同時設定了<code>maxdelays</code>和<code>delay</code>,當監控目錄一直沒有檔案變化了,也會發生同步操作,雖然沒有可rsync的檔案。
to-do: