通過Rsync + inotify實時備份文件

1.引入:

假設一個場景:

有一臺負載服務器slb(ip假設爲:172.17.0.1),還有三臺業務web服務器(ip假設分別爲:172.17.0.8,172.17.0.11,172.17.0.12),每次發佈代碼時,要如何保證這三臺web服務器上的代碼保持一致?

由於我們不可能將代碼挨個web服務器手動上傳,於是需要通過一個“中介”將代碼傳輸給各個web服務器,而rsync配合上inotify就是非常好的“中介”。
在這裏插入圖片描述

2.rsync簡介

Rsync是一種開源的,快速且用途廣泛的文件複製工具。它可以通過任何遠程Shell在本地複製到另一個主機,或從另一個遠程複製到另一個rsync守護程序。它提供了許多選項來控制其行爲的各個方面,並允許非常靈活地指定要複製的文件集。它以其增量傳輸算法而聞名,該算法通過僅發送源文件與目標中現有文件之間的差異來減少通過網絡發送的數據量。 Rsync被廣泛用於備份和鏡像。

在同步備份時,默認情況下,rsync通過其獨特的“quick check”算法,僅同步大小或者最後修改時間發生變化的文件或目錄(也可根據權限,屬主等變化同步,需要制定參數)。甚至是隻同步一個文件裏變化的內容部分,所以可以實現快速的同步數據的功能。

Rsync的特點如下:

  • 支持複製鏈接,設備,所有者,組和權限
  • 可以排除指定文件或目錄同步的功能,與GNU tar的命令類似
  • 可以使用任何的遠程shell工具,包括ssh或rsh
  • 不需要超級用戶權限
  • 文件的管道化傳輸使得延遲最小化
  • 支持匿名或需要驗證的rsync守護進程模式

3.安裝rsync

需要同時在三臺web服務器安裝rsync。
其中一臺web服務器(172.17.0.8)作爲“客戶端”,兩外兩臺(172.17.0.11,172.17.0.12)作爲“服務器”,通過“客戶端”將文件推送到兩臺“服務器”,從而實現文件的同步。

3.1下載rsync

下載地址:https://download.samba.org/pub/rsync/

3.2 編譯安裝

root@3f2a1b9989a3:/var/www/html# tar -zxvf rsync-3.1.3.tar.gz
root@3f2a1b9989a3:/var/www/html# cd rsync-3.1.3
root@3f2a1b9989a3:/var/www/html/rsync-3.1.3# ./configure --prefix=/usr/local/rsync/
root@3f2a1b9989a3:/var/www/html/rsync-3.1.3# make && make install

分別在三臺web服務器輸入/usr/local/rsync/bin/rsync --version如果有顯示版本信息,則說明都已經安裝成功了。

4.配置rsync

4.1 新建用戶

在這裏我們創建一個單獨的用戶專門用於文件的同步:

root@3f2a1b9989a3:/var/www/html# useradd rsync

注意:三臺web服務器都要新增(我的三臺web服務器的IP是:172.17.0.8,172.17.0.11,172.17.0.12)

4.2 rsync配置

將下列內容保存到/etc/rsyncd.conf文件中

#rsync配置文件,配置的註釋不要寫在配置後面,否則會有問題
uid = root
gid = root
use chroot = 0
port = 873
#允許ip訪問設置,請根據實際需要進行配置,爲了方便可以設爲全網段 *,生產環境下爲了安全請指定ip或ip段
#在172.17.0.8主服務器上設爲下列兩臺從服務器的ip,而在兩臺服務器上,這裏應設爲主服務器的ip(172.17.0.8)
hosts allow = 172.17.0.11 172.17.0.12
max connections = 0
timeout = 300
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
transfer logging = yes
syslog facility = local3
#方括號中爲模塊聲明,對應命名,這裏master_web對應了主web機配置,從服務器可都爲[slave_web],方便inotify腳本配置。在172.17.0.8主服務器上可命名爲“master_web”,在172.17.0.11,172.17.0.12這兩臺從服務器上,可以都命名爲"slave_web"
[master_web]
#指定當前模塊在rsync服務器上的同步路徑,該參數是必須指定的
path = /var/www/html/shop/
#註釋,可以同模塊名一樣,從服務器可都爲slave_web
comment = master_web
ignore errors
#是否允許客戶端上傳文件
read only = no
list = no
#指定由空格或逗號分隔的用戶名列表,只有這些用戶才允許連接該模塊
auth users = rsync
#保存密碼和用戶名文件,需要自己生成
secrets file = /etc/rsyncd.passwd

rsyncd.conf配置文件的詳細配置參數,可以參考官網 rsyncd.conf文件配置選項

4.3 生成rsync密碼文件

在主web服務器(172.17.0.8)(不需帶上用戶名):

root@3f2a1b9989a3:/var/www/html# echo "123456" > /etc/rsyncd.passwd

在從web服務器(172.17.0.11,172.17.0.12)(用戶名:密碼):

root@3f2a1b9989a3:/var/www/html# echo "rsync:123456" > /etc/rsyncd.passwd

注意:三臺web服務器的rsync密碼文件/etc/rsyncd.passwd權限一定要設置成600

root@3f2a1b9989a3:/var/www/html# chmod 600 /etc/rsyncd.passwd

5. 啓動rsync

root@9a8a140ce449:/var/www/html# /usr/local/rsync/bin/rsync --daemon --config=/etc/rsyncd.conf

6.文件同步

6.1 編寫shell腳本

只需在主web服務器(172.17.0.8)編寫保存就好

#!/bin/bash
src=/var/www/html/shop/
des=slave_web
user=rsync
host="172.17.0.11 172.17.0.12"
for hostip in $host
do
  rsync -vzrtopg --delete --progress --exclude=/data --exclude=/.git --exclude=/.idea ${src} ${user}@${hostip}::${des} --password-file=/etc/rsyncd.passwd
  echo "${file} was rsynced" >> /var/log/rsync.log 2>&1
done

執行該腳本即可實現:主服務器(172.17.0.8)的/var/www/html/shop/目錄所有文件同步到從服務器(172.17.0.11,172.17.0.12)的/etc/rsyncd.conf配置的slave_web模塊的path目錄,這裏配置的目錄跟主服務器一樣,都爲/var/www/html/shop/
注意:

  • --exclude=/data表示無需同步根目錄下的data目錄,即無需同步/var/www/html/shop/data目錄,如果去掉/,則效果完全不同了,表示的是,無需同步所有名爲data的目錄,如/var/www/html/shop/data/var/www/html/shop/app/data/var/www/html/shop/app/test/data等都不會被同步;
  • src=/var/www/html/shop/要注意最後的/,如果沒有最後一個/,即src=/var/www/html/shop,則表示將/var/www/html目錄下的shop目錄同步到從服務器上;
  • 如果從服務器上/var/www/html/shop/該目錄下有東西,則在同步的時候都會被刪除,以與主服務器保持一致。

具體的rsync命令參數說明,參考官方文檔

至此,我們已經實現了文件的同步了,如果要的只是定時備份下文件,那麼只需要再寫個cron定時任務就可以到此結束了,但在很多場景下,我們需要做到實時同步,這時就需要配合上inotify了。

7.inotify簡介

inotify是基於inode的文件系統通知技術。它提供了僅監視文件系統中文件上各種事件的可能性。它是一個 Linux 內核特性,它監控文件系統,並且及時向專門的應用程序發出相關的事件警告,比如刪除、讀、寫和卸載操作等。Inotify 反應靈敏,用法非常簡單,並且比 cron 任務的繁忙輪詢高效得多。

inotify可以用於以下任務:

  • 檢測文件和目錄中的更改(例如配置文件,郵件目錄)
  • 收集衝突文件及其最終自動恢復
  • 文件使用情況統計和類似目的
  • 自動上傳處理
  • 自動變更備份和版本控制

7.1 安裝inotify工具inotify-tools

inotify-tools 是爲linux下inotify文件監控工具提供的一套c的開發接口庫函數,同時還提供了一系列的命令行工具,這些工具可以用來監控文件系統的事件。 inotify-tools是用c編寫的,除了要求內核支持inotify外,不依賴於其他。
inotify-tools提供兩種工具:

  1. 一是inotifywait,它是用來監控文件或目錄的變化,
  2. 二是inotifywatch,它是用來統計文件系統訪問的次數。

在安裝inotify-tools前要先確認linux系統內核是否達到了2.6.13以上,linux內核版本不低於 2.6.13,系統就支持 inotify,如果linux內核低於2.6.13版本,就需要重新編譯內核加入inotify的支持,也可以用如下方法判斷,內核是否支持inotify:

root@3f2a1b9989a3:/var/www/html# ls -al /proc/sys/fs/ino
inode-nr     inode-state  inotify/
root@3f2a1b9989a3:/var/www/html# ls -al /proc/sys/fs/inotify/
total 0
dr-xr-xr-x 1 root root 0 Jan 14 09:58 .
dr-xr-xr-x 1 root root 0 Jan 14 09:58 ..
-rw-r--r-- 1 root root 0 Jan 14 09:58 max_queued_events
-rw-r--r-- 1 root root 0 Jan 14 09:58 max_user_instances
-rw-r--r-- 1 root root 0 Jan 14 09:58 max_user_watches

如果有上面三項輸出,表示系統已經默認支持inotify,就可以開始安裝inotify-tools了。

下載地址:https://sourceforge.net/projects/inotify-tools/

root@3f2a1b9989a3:/var/www/html# tar -zxvf inotify-tools-3.13.tar.gz
root@3f2a1b9989a3:/var/www/html# cd inotify-tools-3.13
root@3f2a1b9989a3:/var/www/html/inotify-tools-3.13# ./configure --prefix=/usr/local/inotify/
root@3f2a1b9989a3:/var/www/html/inotify-tools-3.13# make && make install

這樣inotify-tools就安裝在/usr/local/inotify目錄了

7.2 改進文件同步shell腳本

因此,將上面的文件同步腳本改進下,讓inotify實時監控其變動並同步文件,如下:

#!/bin/bash
src=/var/www/html/shop/
des=slave_web
user=rsync
host="172.17.0.11 172.17.0.12"
/usr/local/inotify/bin/inotifywait -mrq --exclude "${src}data|${src}\.git|${src}\.idea" --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e modify,delete,create,attrib $src | while read file
do
  for hostip in $host
  do
      rsync -vzrtopg --delete --progress --exclude=/data --exclude=/.git --exclude=/.idea ${src} ${user}@${hostip}::${des} --password-file=/etc/rsyncd.passwd
      echo "${file} was rsynced" >> /var/log/rsync.log 2>&1
  done
done

以上腳本內容保存到/var/www/html目錄的rsync.sh文件。最後,只需在後臺不掛斷的執行該腳本既可實現文件的實時同步了。

root@3f2a1b9989a3:/var/www/html# nohup sh /var/www/html/rsync.sh >> /var/log/nohup.log 2>&1 &

以上就是本文的全部內容了。

思考

上面通過inotify來監控變更的腳本中,一旦同時改動的文件有好多個,那麼豈不是rsync命令要循環執行好多遍,雖然rsync能夠實現增量同步,但是如果項目非常大,rsync每次都要全部循環一遍以便查找變動的文件進行同步,那麼勢必會對CPU以及同步的時延有較大影響,目前暫想不到更好的監控腳本。

發佈了28 篇原創文章 · 獲贊 20 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章