rsync+inotify實現數據實時同步

  rsync(remote sync)是類unix系統中的一款遠程數據同步工具,使用所謂的“rsync算法”來使本地和遠程主機之間的文件達到同步(也可在同一主機內部實現數據同步),這個算法只傳送兩個文件的不同部分,而不是每次都整份傳送,因此速度很快。

  rsync同步數據時,需要掃描所有文件後對比,進行差量傳輸,因此不適宜同步海量小文件,因爲這個掃描對比的過程將會非常耗時。


一、rsync的特性

  ①可以鏡像保存整個目錄樹或文件系統;

  ②較高的數據傳輸效率;

  ③可以藉助於ssh實現安全數據傳輸;

  ④支持匿名傳輸;


二、rsync命令的工作模式

  ⑴shell模式,也稱作本地模式,同一主機內實現數據同步

    rsync [OPTION...] SRC... [DEST]

    例:rsync -avz /etc/httpd/ /tmp/test

  ⑵遠程shell模式,可以利用ssh協議承載其遠程傳輸過程;

    rsync [OPTION...] SRC... [USER@]HOST:DEST

    rsync [OPTION...] [USER@]HOST:SRC... [DEST]

    例:rsync -avz -e 'ssh -p 7788' [email protected]:/etc/fstab /tmp/test

  ⑶列表模式,僅列出源中的內容,-nv

  ⑷服務模式,此時rsync工作爲守護進程,能接收客戶端的數據同步請求;

   ①從服務端拉取數據(pull):

       rsync [OPTION...] [USER@]HOST::SRC... [DEST]   #守護進程模式中服務器的路徑以模塊名打頭

       rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]

       例:rsync -avz [email protected]::tools/test.txt /tmp/

   ②向服務端推送數據(push):

       rsync [OPTION...] SRC... [USER@]HOST::DEST

       rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

       例:rsync -avz /mydata rsync://[email protected]/tools/

  注意:遠程shell模式使用單冒號,守護進程模式使用雙冒號


三、rsync命令的選項

    -n:同步測試,不執行真正的同步過程;

    -v:詳細輸出模式

    -q:靜默模式

    -c:checksum,開啓校驗功能

    -r:遞歸複製  #源路徑若爲目錄,需要指定該選項(或-a)

    -a:歸檔,保留文件的原有屬性;相當於-rptlgoD

    -p:保留文件的權限

    -t:保留文件的時間戳

    -l:保留符號鏈接

    -g:保留屬組

    -o:保留屬主

    -D:保留設備文件

    -e ssh:使用ssh作爲傳輸承載,更安全

        如 -e 'ssh -p 2345'

    -z:壓縮後傳輸

    --delete:刪除那些DST中SRC沒有的文件,此選項能使源和目標完全一致,常用於快速刪除大量數據

    --existing:僅僅更新那些已經存在於DST的文件

    --exclude=PATTERN:指定排除不需要傳輸的文件模式

      如 --exclude=a --exclude={b,c} --exclude={d..g} --exclude=*.txt

    --exclude-from=FILE:排除FILE中指定模式的文件,FILE中的內容要使用相對路徑

    --password-file=FILE:從FILE中得到密碼,僅能應用於rsync服務模式中

    --bwlimit=KBPS  #實際環境中應限制速率,以免導致巨大的CPU消耗

      例:--bwlimit=100(不用帶單位)

    --progress:顯示進度條

    --stats:顯示如何執行壓縮和傳輸

    說明:

      ①rsync命令中,如果源路徑是目錄,且其末尾有“/”,則會複製目錄中的內容,而非目錄本身;如果末尾沒有“/”,則會同步目錄本身及目錄中的所有文件;目標路徑末尾是否有“/”無關緊要;

      ②文件訪問時間等屬性、讀寫等權限、文件內容等有任何變動,都會被認爲修改

      ③目標目錄下如果文件比源目錄還新,則不會同步

[root@node2 ~]# rpm -ql rsync
/etc/xinetd.d/rsync   #rsync若工作於守護進程,可接受超級守護進程管理
/usr/bin/rsync
/usr/share/doc/rsync-3.0.6
/usr/share/doc/rsync-3.0.6/COPYING
/usr/share/doc/rsync-3.0.6/NEWS
/usr/share/doc/rsync-3.0.6/OLDNEWS
/usr/share/doc/rsync-3.0.6/README
/usr/share/doc/rsync-3.0.6/support
...
/usr/share/man/man5/rsyncd.conf.5.gz   #可參考該文檔創建配置文件
[root@node2 ~]# ls /etc/httpd
conf  conf.d  logs  modules  run  ssl
[root@node2 ~]# rsync /etc/httpd/ /tmp/test
skipping directory .   #源路徑若爲目錄,需要指定-r或-a選項,否則不予同步
[root@node2 ~]# rsync -av /etc/httpd/ /tmp/test
sending incremental file list
./
logs -> ../../var/log/httpd
modules -> ../../usr/lib64/httpd/modules
run -> ../../var/run/httpd
conf.d/
conf.d/README
conf.d/php.conf
conf.d/ssl.conf
conf.d/welcome.conf
conf.d/welcome.conf.back
conf/
conf/.htpasswd
conf/httpd.conf
conf/magic
ssl/
ssl/httpd.crt
ssl/httpd.csr
ssl/httpd.key

sent 67856 bytes  received 245 bytes  136202.00 bytes/sec
total size is 66998  speedup is 0.98
[root@node2 ~]# ls /tmp/test
conf  conf.d  logs  modules  run  ssl
[root@node2 ~]# touch /etc/httpd/abc
[root@node2 ~]# rsync -av /etc/httpd/ /tmp/test
sending incremental file list
./
abc   #只會複製變動的部分

sent 481 bytes  received 37 bytes  1036.00 bytes/sec
total size is 66998  speedup is 129.34
[root@node2 ~]# rsync -av /etc/httpd /tmp/test   #源目錄不帶/會連同複製目錄本身
sending incremental file list
httpd/
httpd/abc
httpd/logs -> ../../var/log/httpd
httpd/modules -> ../../usr/lib64/httpd/modules
httpd/run -> ../../var/run/httpd
httpd/conf.d/
httpd/conf.d/README
...

sent 67924 bytes  received 265 bytes  136378.00 bytes/sec
total size is 66998  speedup is 0.98
[root@node2 ~]# ls /tmp/test
abc  conf  conf.d  httpd  logs  modules  run  ssl
[root@node2 ~]# mkdir /tmp/empty   #創建一個空目錄
[root@node2 ~]# rsync -av --delete /tmp/empty/ /tmp/test   #這種用法可用於快速清除大量數據
sending incremental file list
./
deleting ssl/httpd.key
deleting ssl/httpd.csr
deleting ssl/httpd.crt
deleting ssl/
deleting httpd/ssl/httpd.key
...
total size is 0  speedup is 0.00
[root@node2 ~]# ls /tmp/test   #test目錄已被清空
[root@node2 ~]# rsync /etc/fstab [email protected]:/tmp/ceshi   #遠程shell模式
[email protected]'s password:
[root@node2 ~]# rsync -a [email protected]:/etc/selinux/config /tmp/test
[email protected]'s password: 
[root@node2 ~]# ls /tmp/test
config
[root@node1 ~]# ls /tmp/ceshi
fstab


四、rsync的Client-Server模式

  1、rsync服務端

    ⑴爲rsync提供配置文件

      /etc/rsyncd.conf   #修改該配置文件後無須重啓守護進程,每一次客戶端連接都會讀取該文件

      配置文件分兩段:

        全局配置段:一個

        模塊配置段:多個

      配置示例

        # Global Settings

        uid = rsync   #以什麼用戶身份存取模塊目錄

        gid = rsync

        use chroot = no  #chroot爲yes時必須使用root身份

        max connections = 10

        timeout = 300  #該選項可以確保rsync服務器不會永遠等待一個崩潰的客戶端

        strict modes = yes

        pid file = /var/run/rsyncd.pid

        [lock file =  /var/run/rsyncd.lock]

        log file = /var/log/rsyncd.log

        log format = %t %a %m %f %b

        motd file = /etc/rsyncd/rsyncd.motd   #該文件定義客戶端連接時所看到的信息,非必須


        # Directory to be synced

        [tools]    #模塊名

        path = /data   #需要做鏡像的目錄

        comment = some important software  #可給模塊指定描述信息

        ignore errors = yes

        read only = no

        write only = no

        hosts allow = 172.16.0.0/16   #可以是ip、網段、可解析的主機名、域名

        hosts deny = *  #表示所有

        list = false(或no)  #當客戶請求列出可以使用的模塊列表時,該模塊是否應該被列出

        uid = root  #進程以什麼身份對該模塊進行存取;若不指定,則繼承全局配置段中的設定

        gid = root

        exclude = DIR1 DIR2 FILE1...  #排除不要同步的文件或目錄,多個文件或目錄用空格隔開

    ⑵服務端可啓用用戶認證的功能

      ①在全局或模塊配置段中添加:

         auth users = USERNAME LIST

         secrets file = /etc/rsyncd.passwd

         說明:USERNAME LIST爲以逗號分隔的在rsyncd.passwd中存在的用戶名的列表

      ②創建用戶密碼文件/etc/rsyncd.passwd

         格式:username:password

         這裏的用戶名和密碼與操作系統的用戶名密碼無關,可任意指定

         此文件不能允許其它用戶有訪問權限(將其權限設置爲600),且密碼不能超過8個字符

    ⑶創建存取用戶和模塊目錄

        useradd -M -s /sbin/nologin rsync

        mkdir -p /data

        chown -R rsync.rsync /data

    ⑷啓動服務

        當rsync服務器負載較低時,可交由超級守護進程xinetd管理,這也是默認方式

          chkconfig rsync on(或編輯/etc/xinetd.d/rsync文件,將disable 改爲 no)

          service xinetd start   #默認監聽於873/tcp

        當rsync服務器負載較高時,可啓動爲獨立守護進程

          rsync --daemon [--config=FILE] [--port=PORT]

        有時還需要在防火牆上開放端口:

          iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 873 -j ACCEPT

[root@node2 ~]# vim /etc/rsyncd.conf

# Global Settings
uid = nobody
gid = nobody
use chroot = no
max connections = 10
strict modes = yes
timeout = 300
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log

# Directory to be synced
[tools]
path = /data
ignore errors = yes
read only = no
write only = no
hosts allow = 192.168.30.0/24
hosts deny = *
list = false
auth users = tom, jerry
secrets file = /etc/rsyncd.passwd
[root@node2 ~]# vim /etc/rsyncd.passwd   #創建密碼文件

tom:magedu
jerry:linux
rose:titanic
[root@node2 ~]# chmod 600 /etc/rsyncd.passwd
[root@node2 ~]# service xinetd restart
Stopping xinetd:                                           [  OK  ]
Starting xinetd:                                           [  OK  ]
[root@node2 ~]# ss -tnl   #873端口已監聽
...
LISTEN      0      64                     :::873


  2、rsync客戶端

    ⑴生成連接服務端需要的密碼文件

         echo "magedu" >> /etc/rsync.passwd

         chmod 600 /etc/rsync.passwd

    ⑵同步文件

         推送:

           rsync -avz /tmp/ [email protected]::tools --password-file=/etc/rsync.passwd

           rsync -avz /tmp/ rsync://[email protected]/tools --password-file=/etc/rsync.passwd

         拉取:

           rsync -avz [email protected]::tools /tmp/ --password-file=/etc/rsync.passwd

           rsync -avz rsync://[email protected]/tools /tmp/ --password-file=/etc/rsync.passwd


[root@node1 ~]# echo "magedu" >> /etc/rsync.passwd
[root@node1 ~]# chmod 600 /etc/rsync.passwd
[root@node1 ~]# rsync -avz [email protected]::tools/test.txt /tmp/ceshi --password-file=/etc/rsync.passwd  #從rsync服務器拉取數據
...
[root@node1 ~]# ls /tmp/ceshi
test.txt

  測試中遇到一個問題,客戶端向服務器端推送數據不成功,檢查發現配置文件的模塊配置段中未指定uid,因此直接繼承了全局配置段中的uid設定,而全局配置段中的uid = nobody,它對模塊目錄/data沒有寫入權限,從而造成客戶端無法推送數據。

      解決辦法:修改模塊目錄屬主屬組

[root@node1 ~]# rsync -avz iptables.nat [email protected]::tools/ -password-file=/etc/rsync.passwd   #提示向服務器推送數據不成功
rsync: mkstemp ".iptables.nat.6elLqN" (in tools) failed: Permission denied (13)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1039) [sender=3.0.6]
[root@node2 ~]# ls -ld /data
drwxrwxr-x+ 2 root root 4096 Nov 24 22:17 /data
[root@node2 ~]# chown -R nobody.nobody /data
[root@node1 ~]# rsync -avz iptables.nat [email protected]::tools/
...
[root@node2 ~]# ls /data
fstab  iptables.nat  test.txt


六、rsync+inotify 實現數據實時同步

  rsync不能實時地去監測、同步數據,雖然它可以通過crontab(週期性任務計劃)方式觸發同步,但是兩次觸發動作之間必然會有時間差,這樣就可能導致客戶端和服務端數據不一致,無法在應用故障時完全的恢復數據。而rsync+inotify就能夠很好的解決這個問題。

  inotify是一種強大的、細粒度的、異步的文件系統事件監控機制,Linux內核從2.6.13開始引入,允許監控工具(如inotifywait)監控文件系統下文件的各種變化事件,如添加、刪除、修改、移動,當有變動發生時,就觸發rsync同步,從而解決數據同步的實時性問題。

  查看系統是否支持inotify機制

    ls /proc/sys/fs/inotify/,若出現以下三個文件,則支持,否則不支持:

      max_queued_events  max_user_instances  max_user_watches

  數據源是主動同步的一方,而備份源是被動的一方,我們要在數據源上觸發rsync同步操作,由此,應該將數據源作爲rsync客戶端,將備份源作爲rsync服務器端

  1、rsync服務器端配置(略,見上方)

  2、客戶端配置

    ⑴安裝軟件包:

     yum -y install inotify-tools  #inotifywait由inotify-tools包提供

    ⑵提供密碼文件:

     vim /etc/rsync_client.passwd   #只需要輸入一個密碼,就是打算用於連接rsync服務器的用戶對應的密碼

     chmod 600 /etc/rsync_client.passwd

    ⑶編寫同步腳本

     vim /root/scripts/rsync.sh

     chmod +x /root/scripts/rsync.sh

     /root/scripts/rsync.sh &

     echo "nohup /root/scripts/rsync.sh &" >> /etc/rc.local   #讓數據同步腳本隨開機執行

  3、inotifywait

    用法:inotifywait [-hcmrq] [-e <event> ] [-t <seconds> ] [--format <fmt> ] [--timefmt <fmt> ] <file> [ ... ]

    選項:

      -m:監視

      -r:遞歸監視

      -q:減少冗餘信息

      -e/--event:要監視的事件列表;

        可監視的事件:create,delete,modify,move,access,attrib(元數據被修改),open,close

      -t seconds:過期時長,即超出該時長退出監視,缺省爲0,表示無限期監視

      --format:指定事件信息的輸出格式

        %w:發生事件的目錄或文件

        %f:發生事件的文件

        %e:發生的事件

        %T:使用由-timefmt定義的時間格式

      --timefmt:指定時間格式,具體用法可man inotifywait

      --exclude <pattern>:指定排除不需要監視的文件模式

      --fromfile <file>:從file中讀取要監視或排除監視的文件(或目錄),一行一個,不能使用正則表達式,以@開頭的表示排除監視

    例:inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f %e' -e modify,delete,create,move,attrib /tmp/test


  以下node1爲客戶端,node2爲服務端:

[root@node1 ~]# yum -y install inotify-tools   #來自於epel源
...

Installed:
  inotify-tools.x86_64 0:3.14-1.el6                                                                                                                                        

Complete!
[root@node1 ~]# rpm -ql inotify-tools
/usr/bin/inotifywait   #文件系統監視工具
/usr/bin/inotifywatch   #統計文件系統訪問的次數
/usr/lib64/libinotifytools.so.0
/usr/lib64/libinotifytools.so.0.4.1
/usr/share/doc/inotify-tools-3.14
/usr/share/doc/inotify-tools-3.14/AUTHORS
/usr/share/doc/inotify-tools-3.14/COPYING
/usr/share/doc/inotify-tools-3.14/ChangeLog
/usr/share/doc/inotify-tools-3.14/NEWS
/usr/share/doc/inotify-tools-3.14/README
/usr/share/man/man1/inotifywait.1.gz
/usr/share/man/man1/inotifywatch.1.gz
[root@node1 ~]# vim /etc/rsync_client.passwd

magedu
[root@node1 ~]# chmod 600 /etc/rsync_client.passwd

[root@node1 ~]# vim scripts/rsync.sh   #創建數據同步腳本

#!/bin/bash

src=/tmp/test/
log_file=/var/log/rsync_client.log

server=192.168.30.20
user=tom
passwd_path=/etc/rsync_client.passwd
module=tools

inotify_fun(){
    /usr/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f %e' \
          -e modify,delete,create,move,attrib $src | while read file
      do
          /usr/bin/rsync -avz --delete --bwlimit=200 --password-file=${passwd_path} $src $user@$server::$module
      done
}

inotify_fun >> ${log_file} 2>&1 &

[root@node1 ~]# chmod +x !$   #給腳本設置執行權限
chmod +x scripts/rsync.sh

echo "nohup /root/scripts/rsync.sh &" >> /etc/rc.local
[root@node1 ~]# bash -n scripts/rsync.sh   #語法檢查
[root@node1 ~]# scripts/rsync.sh &
[1] 6155
[root@node1 ~]# echo "nohup /root/scripts/rsync.sh &" >> /etc/rc.local
[root@node1 ~]# cp a.txt anaconda-ks.cfg /tmp/test 
[root@node1 ~]# ls /tmp/test
anaconda-ks.cfg  a.txt  tesla.txt
[root@node2 ~]# ls /data
anaconda-ks.cfg  a.txt  tesla.txt
[root@node1 ~]# rm -f /tmp/test/a.txt
[root@node2 ~]# ls /data
anaconda-ks.cfg  tesla.txt


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章