2014年1月16日 星期四

如何快速同步兩台server之間的檔案

 如果我們有一些檔案同時分散在兩台不同的server,而且這些分散的檔案都會被更新,我們的目的是希望這些異動的檔案能自動同步到另一台,讓兩台之間的檔案都能保存同步且一致。

  目前Linux有幾種檔案同步的工具,像rsync或duplicati,然而,這些工具都是屬於「單向」的檔案同步(從同一方向進行檔案的推/送作業),如果要達到「雙向」的同步,就必須分別執行二次不同方向的同步作業。

    Unison(http://www.cis.upenn.edu/~bcpierce/unison/)是屬於開放原始碼的檔案同步工具,它支援雙向的檔案同步,並且也支援各種不同的平台,如LinuxFreeBSDWindows以及Mac OS X。在Linux平台,Unison除了GUI圖形介面外,亦提供了指令模式可使用

    下面將介紹,如何使用Unison指令模式來同步兩台server之間的檔案。

在Linux安裝Unison
    您可以透過apt-get或yum的方式來安裝Unison,例如,在CentOS安裝Unison,我們會輸入
    $ sudo yum install unison

    如果您發現找不到Unison無法安裝,您可能需要先安裝EPEL(Extra Packages for Enterprise Linux),請參考http://www.thegeekstuff.com/2012/06/enable-epel-repository/

    安裝好Unison之後,如果您是在圖形介面模式下輸入unison,會出現下方的對話框,讓您開始一個同步的工作。

若您是在文字模式,則不會出現下方的訊息;本文將介紹的是unison文字模式的操作。
$ unison
Usage: unison [options]
   or unison root1 root2 [options]
   or unison profilename [options]

For a list of options, type "unison -help".
For a tutorial on basic usage, type "unison -doc tutorial".
For other documentation, type "unison -doc topics".

立即同步試看看
    環境準備:我們準備兩台已經安裝了unison的linux機器,並且分別在/home/chtseng下建立syncFiles資料夾,並放一些檔案進去。

    執行看看:我們在其中一台執行下方的指令
[chtseng@itgallery ~]$ unison ~/syncFiles ssh://chtseng@172.30.16.83//home/chtseng/syncFiles
Contacting server...
The authenticity of host '172.30.16.83 (172.30.16.83)' can't be established.
RSA key fingerprint is 4b:60:43:6f:30:a0:de:46:4a:b8:ed:2d:96:a0:c2:44.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.30.16.83' (RSA) to the list of known hosts.
chtseng@172.30.16.83's password:
Connected [//chtseng-nb//home/chtseng/syncFiles -> //itgallery//home/chtseng/syncFiles]
Looking for changes
Warning: No archive files were found for these roots, whose canonical names are:
       /home/chtseng/syncFiles
       //chtseng-nb//home/chtseng/syncFiles
This can happen either
because this is the first time you have synchronized these roots,
or because you have upgraded Unison to a new version with a different
archive format.

Update detection may take a while on this run if the replicas are
large.

Unison will assume that the 'last synchronized state' of both replicas
was completely empty.  This means that any files that are different
will be reported as conflicts, and any files that exist only on one
replica will be judged as new and propagated to the other replica.
If the two replicas are identical, then no changes will be reported.

If you see this message repeatedly, it may be because one of your machines
is getting its address from DHCP, which is causing its host name to change
between synchronizations.  See the documentation for the UNISONLOCALHOSTNAME
environment variable for advice on how to correct this.

Donations to the Unison project are gratefully accepted:
http://www.cis.upenn.edu/~bcpierce/unison

Press return to continue.[<spc>]   Waiting for changes from server
Reconciling changes
local          chtseng-nb
file     ---->            TestSync1.txt  [f] f
        <---- file       inNB.txt  [f]
file     ---->            syncTest.txt  [f] f

Proceed with propagating updates? []
No default command [type '?' for help]
Proceed with propagating updates? [] y
Propagating updates
UNISON 2.27.57 started propagating changes at 10:11:22 on 16 Jan 2014
[BGN] Copying TestSync1.txt from /home/chtseng/syncFiles to //chtseng-nb//home/chtseng/syncFiles
[BGN] Copying inNB.txt from //chtseng-nb//home/chtseng/syncFiles to /home/chtseng/syncFiles
[BGN] Copying syncTest.txt from /home/chtseng/syncFiles to //chtseng-nb//home/chtseng/syncFiles
[END] Copying inNB.txt
[END] Copying TestSync1.txt
[END] Copying syncTest.txt
UNISON 2.27.57 finished propagating changes at 10:11:22 on 16 Jan 2014
Saving synchronizer state
Synchronization complete  (3 items transferred, 0 skipped, 0 failures)

    您會看到,由於是第一次連線,會先有SSH的認證確認及密碼,再來是檔案複製動作的確認,OK後便開始進行同步;首先會從命令發送端同步到client(另一台),完成後再從client同步回來。

相同檔案但內容不同的處理
這部份是unison比起其它單向同步工具最方便的地方了;若過程中有相同名稱的檔案會詢問如何處理,例如下方的範例,兩邊皆有inNB.txt這個檔案但內容不同,表示雙都有modify過,此時,您可以先按?看看可以選擇的動作
local          chtseng-nb
changed  <-?-> changed    inNB.txt  [] ?
Commands:
 f                     follow unison's recommendation (if any)
 I                     ignore this path permanently
 E                     permanently ignore files with this extension
 N                     permanently ignore paths ending with this name
 m                     merge the versions
 d                     show differences
 x                     show details
 L                     list all suggested changes tersely
 l                     list all suggested changes with details
 p or b                go back to previous item
 g                     proceed immediately to propagating changes
 q                     exit unison without propagating any changes
 /                     skip
 > or .                propagate from from local to chtseng-nb
 < or ,                propagate from from chtseng-nb to local

您可以參考上列的所有動作,其中比較重要的有:m合併、d顯示差異地方、x顯示雙方的檔案資料、/ 跳過不動作、> 從server端覆蓋過去、< 從client覆蓋過來
建立Unison設定檔  
除了直接下指令之外,另一個作法是,我們可以先建立好設定檔,再讓unison來引用,這樣可以更方便的在cronjob裏使用,我們在修改或管理所有的同步設定時也更方便。

首先,我們要在一台會發動同步的server上建立Unison profile檔;Unison profile是副檔名為.prf的純文字檔,定義了一些檔案同步的設定,如根目錄、包含或排除的目錄或檔案特徵等。
   
    Unison profile可以放置在系統的任何地方,但前提是您要將Unison profile的路徑定義在UNISON這個環境變數中;如果Unison發現UNISON環境變數沒有定義,它預設就會在$HOME/.unison這個目錄中尋找Unison profile。

    剛安裝完成Unison之後,如果您沒有定義UNISON變數,那麼,您會發現~/.unison目錄下的default.prf內容是空的,只有一行’ # Unison preferences file’,我們必須自行來定義其內容。

下方是我們建立的Unison profile的內容
# Two root directories to sync.
# You can use ssh:// to sync over SSH
root = /home/chtseng/syncFiles
root = ssh://chtseng@172.30.16.83//home/chtseng/syncFiles

# 如果只是想單向同步,而不要雙向的同步,那麼必須要在force中指定要單向同步的path.
# force = /home/alice/sync_folder

# 如果不想要在同步過程中因unison詢問而暫停,請設定batch=true
batch = true

# 檔案衝突的處理方式,設定為auto可讓unison決定最適合的處理方式而不會暫停等候使用者決定:
auto = true

# 您也可以在此輸入同步路徑下的資料名稱(不含root已定義的path,ex: 您想要同步的是/home/chtseng/syncFiles/cdfiles,則path = cdfiles).
# path = dir1
# path = dir2

#若有要忽略不予同步的檔案,可定義在ignore參數.
# ignore = Name *.o
# ignore = Name *~
# ignore = Path */temp/archive_*

#是否忽略雙方的檔案權限:
perms = 0

    設定完之後,儲存為sync1.prf,我們便可以直接下unison sync1 執行同步作業。
$ unison sync1
Contacting server...
chtseng@172.30.16.83's password:
Connected [//chtseng-nb//home/chtseng/syncFiles -> //itgallery//home/chtseng/syncFiles]
Looking for changes
 Waiting for changes from server
Reconciling changes
changed  <-?-> changed    inNB.txt
local        : changed file       modified on 2014-01-16 at 10:28:50  size 54        unknown permissions
chtseng-nb   : changed file       modified on 2014-01-16 at 10:27:13  size 48        unknown permissions
No updates to propagate


Unison的使用相當方便,它可以一次就完成雙向的同步,且方便的讓我們定義一些同步的處理方式,此外,執行同步動作時,它也可指定要使用ssh或rsync的方式來執行。可惜的是它並不是linux預設安裝的package,除了下載tar ball來手動安裝外,若要透過yum或apt-get自動安裝,需先安裝epel才行。

沒有留言:

張貼留言