2018年8月2日 星期四

Lsyncd - Live syncing Daemon 資料夾同步

  在 Linux 上若要將兩個資料夾同步,大部分會想到用 rsync 這個指令,在第二次同步時,它會比對兩個資料夾不同之處,而只同步這些不同之處,所以相對之下,在第二次之後的同步,是較快速,較省網路流量的。如果兩個資料夾是分處於兩台不同電腦上,rsync 還可以使用 ssh 加密連線來傳輸資料。再搭配上系統排程 cron,即可達成定時同步的需求。

如果須要的是即時同步,那 rsync 就只能把 cron 的時間間隔縮短,但要縮多短?如果資料夾內資料較多,rsync 比對的時間就會拉長,所以根本無法確定同步的時間間隔該設定多少,而且資料越多,時間間隔就須越長,就越不即時....

這裡要介紹的 lsyncd 指令,它是基於 inotify(註¹) 的檔案監測機制,當檔案或資料夾有變動時,inotify 會記錄下來並回復 lsycnd 檔案已更動,lsyncd 預設每 20 秒同步這些已更動過的檔案,若要同步的目的地資料夾是在別台電腦,lsyncd 支援使用 ssh 加密連線來傳輸資料。

雖說 lsyncd 也不算是即時同步,但把同步時間縮短到每秒,其效果也算接近即時同步了。



安裝 lsyncd:

請注意,這裡是以 CentOS 6.8 來做安裝說明,若您的 Linux 版本不同,可能有部份步驟不同。



  1. CentOS 6.8 本身並無附帶 lsyncd 套件,必須從 EPEL(註²) 軟體包中安裝,所以得先裝 EPEL 軟體包:

    yum install -y epel-release




  2. 安裝 lsyncd 套件:

    yum install -y lsyncd



  3. 編輯設定檔 /etc/lsyncd.conf

    vi /etc/lsyncd.conf

    設定檔中, -- 以後的文字皆僅是說明,而非設定內容。所以預設的說明檔內只有幾行說明,沒有其它內容,我們必需自行新增須要的內容。

    由於 lsyncd 是以 lua(註³) 語言編成,所以其設定檔須為有效的 lua 語法。
    設定檔內基本要有兩個段落,settings 及 sync,且皆以大括號{}包起來,中間放置各自的設定項目。settings 段落主要是放全域的設定項,而 sync 落則是放同步資料夾的細項。如果有某些項目在兩個段落中都有,則以 sync 段落中的為主;若細項只寫在 settings 段落中,其它 sync 段落中都沒有,則表示所有 sync 段落都套用 settings 段落中的細項。

    請在設定檔中加入下列:

    settings {
    --settings 段落,以大括號包起來,中間放其它細項。

    logfile = "/var/log/lsyncd/lsyncd.log",
    --這裡指定 logfile 的位置。
    --這個版本其實已經在系統的 logrotate 中指定了 log 檔位置,
    --所以如果你要改變 log 檔的位置的話,
    --請同時修改 logrotate 的設定 (/etc/logrotate.d/lsyncd)。
    --每一細項下面還有另一細項時,須以逗號(,)結尾。


    statusFile = "/var/run/lsyncd/lsyncd.status"
    --同步狀態記錄檔。本版已經在 /var/run 內建立了 lsyncd 資料夾,所以您就別再改位置了。

    }
    --settings 段落的結尾括號。


    sync {
    --sync 段落開始。

    default.direct,
    --同步方式為 direct 時,表示是本機資料夾同步,
    --第一次同步用 rsync,再來用 cp, move, delete。

    source  = "/home/user/src/",
    --來源資料夾。

    target  = "/home/user/trg/"
    --目的資料夾。

    }
    --sync 段落的結尾括號。




    --若有兩組以上資料夾要同步,就多設幾組 sync 段落來對應即可。




    sync {
    --sync 段落開始。

    default.rsync,
    --同步方式為 rsync 時,可以做本機或異地資料夾同步。
    --全程用 rsync 指令同步,而不用 cp, move, delete。


    source = "/home/user/src/",
    --來源資料夾。

    target = "/home/user/trg/",
    --本機端目的資料夾。
    --或者是
    --
    target = "192.168.0.100:/home/usr/trg/",
    --遠端目的資料夾。

    delay = 5,
    -- 每 5 秒同步一次。
    exclude = "abc.tmp",
    -- 排除,不同步 abc.tmp 這個檔。

    rsync {
    --要給 rsync 指令的參數集段落。

    binary = "/usr/bin/rsync",
    -- rsync 指令的絕對路徑。
    -- 請注意您採用之 linux 版本的 rsync 指令位置,各版恐有不同,
    -- 您可用下列指令查詢:which rsync


    archive = true,
    -- 等於 rsync  的 -a 參數。

    compress = true,
    -- 傳輸前是否壓縮,等於 rsync 的 -z 參數。    
    -- 有壓縮,網路傳輸較快,較耗 cpu 資源。

    verbose = true
    -- rsync 執行時,顯示較多資訊。


    }
    -- rsync 指令參數集段落結尾。

    }
    -- sync 段落結尾。


    sync {

    default.rsyncssh,
    -- 同步方式為 rsyncssh 時,表示全程使用 rsync 同步,並使用 ssh 連線。
    -- 這裡您必須要先設定好 ssh 用 key 連到目的地主機才行,參考資料

    source = "/home/user/src/",
    -- 來源資料夾。

    host = "192.168.0.100",
    -- 目的地電腦。

    targetdir = "/home/user/trg",
    -- 目的地資料夾。

    delay = 1,
    -- 每秒同步一次。

    exclude = {
    -- 排除,用列表的方式設定。

    "abc.tmp",
    -- 不同步 abc.tmp 這個檔。

    "tmp/",
    -- 不同步 tmp 這個資料夾。

    "*.log"
    -- 不同步副檔名為 .log 的檔案。
    }
    -- 排除項目的結尾括號。

    rsync = {
    binary = "/usr/bin/rsync",
    archive = true,
    compress = true,
    verbose = true
    }


    ssh = {
    port = 22
    -- 如果您的 ssh 有改 Port,可以在這設定。
    -- 如果沒有改,這段落是可以省略的。

    }

    }
    -- sync 段落的結尾大括號。


  4. 操作 lsyncd:

    service lsyncd start
    啟動 lsyncd。

    service lsyncd restart
    重新啟動 lsyncd。

    service lsyncd stop
    停止 lsyncd。

    service lsyncd reload
    重新讀取 /etc/lsyncd.conf 設定檔。

    service lsyncd status顯示 lsyncd 當前狀況。

    chkconfig lsyncd on
    設定開機時啟動 lsyncd

    chkconfig lsyncd off
    設定開機時不要啟動 lsyncd


  5. 補充:

    檢查可監測數量設定值:
    lsyncd 是依靠 kernel 內建的檔案監測功能 inotify,來回報記錄檔案狀態,而 inotify 預設有設定了一個可監測資料夾數量的限定值。

    cat /proc/sys/fs/inotify/max_user_watches

    在 CentOS 6.8 內,它預設值是 8192,也就是它只能監測最多 8192 個資料夾。
    而我們要同步的資料夾有多少,會不會超過這個數值呢?必竟,若是超過了,它就無法同步到了。

    cat /var/run/lsyncd/lsyncd.status

    在狀態檔中找到一行如下:
    Inotify watching 1440 directories
    那數字便是目前 lsyncd 所監測的資料夾數量。
    如果您看到的數字很靠近 8192 或甚至超過,那就必須放大這個限定值。

    echo '10000' > /proc/sys/fs/inotify/max_user_watches

    這樣可以即時把限定值改成 10000,但重開機後它又會變成原本的 8192。
    下面方法可以改變開機後的預設值:

    把上述即時修改的指令放到 rc.local 之類的開機啟動檔內。
    或是
    /etc/sysctl.conf 內加上一行
    fs.inotify.max_user_watches = 10000

    這樣它重開機後,一樣會放大成我們設定的數值。













註¹:inotify 是在 Linux 下的一套文件監測的機制,從 kernel 2.6.13 以後納入核心功能,只要被監測的檔案或資料夾被新增,修改,刪除,開啟,關閉等等動作都會被記錄下來。參考資料 https://github.com/rvoicilas/inotify-tools/wiki 


註²:Extra Packages for Enterprise Linux(EPEL) 是由 Fedora 社群專為 Enterprise Linux 創建,維護及管理一系列的額外軟體包,適用的 Linux 包括但不限於 RedHat Enterprise Linux,CentOS Linux,Scientific Linux 及 Oracle Linux。安裝方式請參考 https://www.iq180.com.tw。官方資料:https://fedoraproject.org/wiki/EPEL


註³:Lua 是一個開源且功能強大,高效,輕量級,可嵌入的腳本語言,它支持過程編程,面向對象編程,函數編程,數據驅動編程和數據描述。Lua 的速度很快,且已被大量應用,如魔獸世界和憤怒鳥等....參考資料:http://www.lua.org/




沒有留言: