歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux下inotify rsync使用詳解

Linux下inotify rsync使用詳解

日期:2017/2/27 15:53:36   编辑:Linux教程

1. rsync

1.1 什麼是rsync

rsync是一個遠程數據同步工具,可通過LAN/WAN快速同步多台主機間的文件。它使用所謂的“Rsync演算法”來使本地和遠程兩個主機之間 的文件達到同步,這個算法只傳送兩個文件的不同部分,而不是每次都整份傳送,因此速度相當快。所以通常可以作為備份工具來使用。

運行Rsync server的機器也叫backup server,一個Rsync server可同時備份多個client的數據;也可以多個Rsync server備份一個client的數據。Rsync可以搭配ssh甚至使用daemon模式。Rsync server會打開一個873的服務通道(port),等待對方rsync連接。連接時,Rsync server會檢查口令是否相符,若通過口令查核,則可以開始進行文件傳輸。第一次連通完成時,會把整份文件傳輸一次,下一次就只傳送二個文件之間不同的 部份。

基本特點:

  1. 可以鏡像保存整個目錄樹和文件系統;
  2. 可以很容易做到保持原來文件的權限、時間、軟硬鏈接等;
  3. 無須特殊權限即可安裝;
  4. 優化的流程,文件傳輸效率高;
  5. 可以使用rcp、ssh等方式來傳輸文件,當然也可以通過直接的socket連接;
  6. 支持匿名傳輸。

命令語法:
rsync的命令格式可以為以下六種:
 rsync [OPTION]… SRC DEST
 rsync [OPTION]… SRC [USER@]HOST:DEST
 rsync [OPTION]… [USER@]HOST:SRC DEST
 rsync [OPTION]… [USER@]HOST::SRC DEST
 rsync [OPTION]… SRC [USER@]HOST::DEST
 rsync [OPTION]… rsync://[USER@]HOST[:PORT]/SRC [DEST]

對應於以上六種命令格式,我們可以總結rsync有2種不同的工作模式:

  • shell模式:使用遠程shell程序(如ssh或rsh)進行連接。當源路徑或目的路徑的主機名後面包含一個冒號分隔符時使用這種模式,rsync安裝完成後就可以直接使用了,無所謂啟動。(目前沒有嘗試過這個方法)
  • daemon模式:使用TCP直接連接rsync daemon。當源路徑或目的路徑的主機名後面包含兩個冒號,或使用rsync://URL時使用這種模式,無需遠程shell,但必須在一台機器上啟動rsync daemon,默認端口873,這裡可以通過rsync --daemon使用獨立進程的方式,或者通過xinetd超級進程來管理rsync後台進程。

當rsync作為daemon運行時,它需要一個用戶身份。如果你希望啟用chroot,則必須以root的身份來運行daemon,監聽端口,或 設定文件屬主;如果不啟用chroot,也可以不使用root用戶來運行daemon,但該用戶必須對相應的模塊擁有讀寫數據、日志和lock file的權限。當rsync以daemon模式運行時,它還需要一個配置文件——rsyncd.conf。修改這個配置後不必重啟rsync daemon,因為每一次的client連接都會去重新讀取該文件。

我們一般把DEST遠程服務器端成為rsync Server,運行rsync命令的一端SRC稱為Client。

安裝:
rsync在CentOS6上默認已經安裝,如果沒有則可以使用yum install rsync -y,服務端和客戶端是同一個安裝包。

# rsync -h

1.2 同步測試

1.2.1 本機文件夾同步

# rsync -auvrtzopgP --progress  /root/ /tmp/rsync_bak/

會看到從/root/傳輸文件到/tmp/rsync_bak/的列表和速率,再運行一次會看到sending incremental file list下沒有復制的內容,可以在/root/下touch某一個文件再運行看到只同步了修改過的文件。

上面需要考慮以下問題:

  • 刪除/root/下的文件不會同步刪除/tmp/rsync_bak,除非加入--delete選項
  • 文件訪問時間等屬性、讀寫等權限、文件內容等有任何變動,都會被認為修改
  • 目標目錄下如果文件比源目錄還新,則不會同步
  • 源路徑的最後是否有斜槓有不同的含義:有斜槓,只是復制目錄中的文件;沒有斜槓的話,不但要復制目錄中的文件,還要復制目錄本身

1.3 同步到遠程服務器

在服務器間rsync傳輸文件,需要有一個是開著rsync的服務,而這一服務需要兩個配置文件,說明當前運行的用戶名和用戶組,這個用戶名和用戶 組在改變文件權限和相關內容的時候有用,否則有時候會出現提示權限問題。配置文件也說明了模塊、模塊化管理服務的安全性,每個模塊的名稱都是自己定義的, 可以添加用戶名密碼驗證,也可以驗證IP,設置目錄是否可寫等,不同模塊用於同步不同需求的目錄。

1.3.1 服務端配置文件

** /etc/rsyncd.conf: **

#2014-12-11 by Sean
uid=root
gid=root
use chroot=no
max connections=10
timeout=600
strict modes=yes
port=873
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
log file=/var/log/rsyncd.log

[module_test]
path=/tmp/rsync_bak2
comment=rsync test logs
auth users=sean
uid=sean
gid=sean
secrets file=/etc/rsyncd.secrets
read only=no
list=no
hosts allow=172.29.88.204
hosts deny=0.0.0.0/32

這裡配置socket方式傳輸文件,端口873,[module_test]開始定義一個模塊,指定要同步的目錄(接收)path,授權用戶,密碼文件,允許哪台服務器IP同步(發送)等。

經測試,上述配置文件每行後面不能使用#來來注釋

** /etc/rsyncd.secrets: **

sean:passw0rd

一行一個用戶,用戶名:密碼。請注意這裡的用戶名和密碼與操作系統的用戶名密碼無關,可以隨意指定,與/etc/rsyncd.conf中的auth users對應。

修改權限:chmod 600 /etc/rsyncd.d/rsync_server.pwd

1.3.2 服務器啟動rsync後台服務

修改/etc/xinetd.d/rsync文件,disable 改為 no

# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#   allows crc checksumming etc.
service rsync
{
    disable = no
    flags       = IPv6
    socket_type     = stream
    wait            = no
    user            = root
    server          = /usr/bin/rsync
    server_args     = --daemon
    log_on_failure  += USERID
}

執行service xinetd restart會一起重啟rsync後台進程,默認使用配置文件/etc/rsyncd.conf。也可以使用/usr/bin/rsync --daemon --config=/etc/rsyncd.conf

為了以防rsync寫入過多的無用日志到/var/log/message(容易塞滿從而錯過重要的信息),建議注釋掉/etc/xinetd.conf的success:

# log_on_success  = PID HOST DURATION EXIT

如果使用了防火牆,要添加允許IP到873端口的規則。

# iptables -A INPUT -p tcp -m state --state NEW  -m tcp --dport 873 -j ACCEPT
# iptables -L  查看一下防火牆是不是打開了 873端口
# netstat -anp|grep 873

建議關閉selinux,可能會由於強訪問控制導致同步報錯。

1.3.3 客戶端測試同步

單向同步時,客戶端只需要一個包含密碼的文件。
/etc/rsync_client.pwd:

passw0rd

chmod 600 /etc/rsync_client.pwd

命令:
將本地/root/目錄同步到遠程172.29.88.223的/tmp/rsync_bak2目錄(module_test指定):

/usr/bin/rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd /root/ [email protected]::module_test 

當然你也可以將遠程的/tmp/rsync_bak2目錄同步到本地目錄/root/tmp:

/usr/bin/rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd [email protected]::module_test /root/ 

從上面兩個命令可以看到,其實這裡的服務器與客戶端的概念是很模糊的,rsync daemon都運行在遠程172.29.88.223上,第一條命令是本地主動推送目錄到遠程,遠程服務器是用來備份的;第二條命令是本地主動向遠程索取 文件,本地服務器用來備份,也可以認為是本地服務器恢復的一個過程。

1.4 rsync不足

與傳統的cp、tar備份方式相比,rsync具有安全性高、備份迅速、支持增量備份等優點,通過rsync可以解決對實時性要求不高的數據備份需求,例如定期的備份文件服務器數據到遠端服務器,對本地磁盤定期做數據鏡像等。

隨著應用系統規模的不斷擴大,對數據的安全性和可靠性也提出的更好的要求,rsync在高端業務系統中也逐漸暴露出了很多不足,首先,rsync同 步數據時,需要掃描所有文件後進行比對,進行差量傳輸。如果文件數量達到了百萬甚至千萬量級,掃描所有文件將是非常耗時的。而且正在發生變化的往往是其中 很少的一部分,這是非常低效的方式。其次,rsync不能實時的去監測、同步數據,雖然它可以通過crontab方式進行觸發同步,但是兩次觸發動作一定 會有時間差,這樣就導致了服務端和客戶端數據可能出現不一致,無法在應用故障時完全的恢復數據。基於以上原因,rsync+inotify組合出現了!

2. inotify-tools

2.1 什麼是inotify

inotify是一種強大的、細粒度的、異步的文件系統事件監控機制,Linux內核從2.6.13開始引入,允許監控程序打開一個獨立文件描述符,並針對事件集監控一個或者多個文件,例如打開、關閉、移動/重命名、刪除、創建或者改變屬性。

CentOS6自然已經支持:
使用ll /proc/sys/fs/inotify命令,是否有以下三條信息輸出,如果沒有表示不支持。

total 0
-rw-r--r-- 1 root root 0 Dec 11 15:23 max_queued_events
-rw-r--r-- 1 root root 0 Dec 11 15:23 max_user_instances
-rw-r--r-- 1 root root 0 Dec 11 15:23 max_user_watches
  • /proc/sys/fs/inotify/max_queued_evnets表示調用inotify_init時分配給inotify instance中可排隊的event的數目的最大值,超出這個值的事件被丟棄,但會觸發IN_Q_OVERFLOW事件。
  • /proc/sys/fs/inotify/max_user_instances表示每一個real user ID可創建的inotify instatnces的數量上限。
  • /proc/sys/fs/inotify/max_user_watches表示每個inotify instatnces可監控的最大目錄數量。如果監控的文件數目巨大,需要根據情況,適當增加此值的大小。

inotify-tools:

inotify-tools是為linux下inotify文件監控工具提供的一套C的開發接口庫函數,同時還提供了一系列的命令行工具,這些工具 可以用來監控文件系統的事件。 inotify-tools是用c編寫的,除了要求內核支持inotify外,不依賴於其他。inotify-tools提供兩種工具,一是inotifywait,它是用來監控文件或目錄的變化,二是inotifywatch,它是用來統計文件系統訪問的次數。

下載inotify-tools-3.14-1.el6.x86_64.rpm,通過rpm包安裝:

# rpm -ivh /apps/crm/soft_src/inotify-tools-3.14-1.el6.x86_64.rpm 
warning: /apps/crm/soft_src/inotify-tools-3.14-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 4026433f: NOKEY
Preparing...                ########################################### [100%]
   1:inotify-tools          ########################################### [100%]
# rpm -qa|grep inotify
inotify-tools-3.14-1.el5.x86_64

2.2 inotifywait使用示例

監控/root/tmp目錄文件的變化:

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

上面的命令表示,持續監聽/root/tmp目錄及其子目錄的文件變化,監聽事件包括文件被修改、刪除、創建、移動、屬性更改,顯示到屏幕。執行完上面的命令後,在/root/tmp下創建或修改文件都會有信息輸出:

2014/12/11-15:40:04 /root/tmp/ new.txt
2014/12/11-15:40:22 /root/tmp/ .new.txt.swp
2014/12/11-15:40:22 /root/tmp/ .new.txt.swx
2014/12/11-15:40:22 /root/tmp/ .new.txt.swx
2014/12/11-15:40:22 /root/tmp/ .new.txt.swp
2014/12/11-15:40:22 /root/tmp/ .new.txt.swp
2014/12/11-15:40:23 /root/tmp/ .new.txt.swp
2014/12/11-15:40:31 /root/tmp/ .new.txt.swp
2014/12/11-15:40:32 /root/tmp/ 4913
2014/12/11-15:40:32 /root/tmp/ 4913
2014/12/11-15:40:32 /root/tmp/ 4913
2014/12/11-15:40:32 /root/tmp/ new.txt
2014/12/11-15:40:32 /root/tmp/ new.txt~
2014/12/11-15:40:32 /root/tmp/ new.txt
...

3. rsync組合inotify-tools完成實時同步

這一步的核心其實就是在客戶端創建一個腳本rsync.sh,適用inotifywait監控本地目錄的變化,觸發rsync將變化的文件傳輸到遠程備份服務器上。為了更接近實戰,我們要求一部分子目錄不同步,如/root/tmp/log和臨時文件。

3.1 創建排除在外不同步的文件列表

排除不需要同步的文件或目錄有兩種做法,第一種是inotify監控整個目錄,在rsync中加入排除選項;第二種是inotify排除部分不監控的目錄,rsync自然也不會觸發。我們選擇第二種。

這個操作在客戶端進行,/root/tmp/log以及/root/tmp/src目錄下的js、css和一些臨時文件不同步,所以不需要inotifywait/root/tmp下的其他文件和目錄都同步。(其實對於打開的臨時文件,可以不監聽modify時間而改成監聽close_write

# vi /etc/inotify_rsync_exclude.lst:
@/root/tmp/cache??*
@/root/tmp/src/js
@/root/tmp/src/css
@/root/tmp/src
@/root/tmp/src/20*/20*/20*/.??*
@/root/tmp/log/

目前測試看到只能用絕對路徑。

3.2 客戶端同步到遠程的腳本rsync.sh

rsync.sh:

#rsync auto sync script with inotify
#2014-12-11 Sean
#variables
current_date=$(date +%Y%m%d_%H%M%S)
source_path=/root/tmp/
log_file=/var/log/rsync_client.log

#rsync
rsync_server=172.29.88.223
rsync_user=sean
rsync_pwd=/etc/rsync_client.pwd
rsync_module=module_test

#rsync client pwd check
if [ ! -e ${rsync_pwd} ];then
    echo -e "rsync client passwod file ${rsync_pwd} does not exist!"
    exit 0
fi

#inotify_function
inotify_fun(){
    /usr/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f' \
          --fromfile /etc/inotify_rsync_exclude.lst -e modify,delete,create,move,attrib ${source_path} \
          | while read file
      do
          /usr/bin/rsync -auvrtzopgP --progress --bwlimit=200 --password-file=${rsync_pwd} ${source_path} ${rsync_user}@${rsync_server}::${rsync_module} 
      done
}

#inotify log
inotify_fun >> ${log_file} 2>&1 &

--bwlimit=200用於限制傳輸速率最大200kb,因為在實際應用中發現如果不做速率限制,會導致巨大的CPU消耗。

在客戶端運行腳本# ./rsync.sh即可實時同步目錄。

Copyright © Linux教程網 All Rights Reserved