Rsync+inotify實現檔案實時同步#附shell指令碼
強烈推薦先仔細看此文
https://segmentfault.com/a/1190000002427568
實驗環境
centos 7.3
vm2:192.168.221.128 同步伺服器
vm1:192.168.221.129 上傳伺服器
關閉seliunx
關閉防火牆
同步伺服器vm2的配置
yum install rsync
建立rsyncd.conf配置檔案:
log file = /var/log/rsyncd.log pidfile = /var/run/rsyncd.pid lock file = /var/run/rsync.lock secrets file = /etc/rsync.pass #使用者認證配置檔案,裡面儲存使用者名稱稱和密碼,後面會建立這個檔案 motd file = /etc/rsyncd.Motd #rsync啟動時歡迎資訊頁面檔案位置(檔案內容自定義) [Sync] #同步模組名稱 path = /data/wwwroot/sync/ #rsync服務端資料目錄路徑(最後面的“/”很重要) comment = Sync uid = root gid = root port=873 use chroot = no read only = no list = no #不顯示rsync服務端資源列表 max connections = 200 timeout = 600 auth users = root #執行資料同步的使用者名稱,可以設定多個,用英文狀態下逗號隔開 hosts allow = 192.168.221.129#允許進行資料同步的客戶端IP地址,可以設定多個,用英文狀態下逗號隔開 hosts deny = 0.0.0.0/32
建立使用者認證檔案
#vim /etc/rsync.pass
user1:123456 #格式,使用者名稱:密碼,可以設定多個,每行一個使用者名稱:密碼
設定檔案許可權
chmod 600 /etc/rsyncd.conf #設定檔案所有者讀取、寫入許可權
chmod 600 /etc/rsync.pass #設定檔案所有者讀取、寫入許可權
啟動rsync
#/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
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連線都會去重新讀取該檔案。
釋出伺服器vm1的配置
#yum install rsync
建立認證密碼檔案
vim /etc/passwd.txt
123456 #只需要填寫密碼即可,不用像rsync.pass需要用“使用者:密碼”的格式
chmod 600 /etc/passwd.txt #設定檔案許可權,只設置檔案所有者具有讀取、寫入許可權即可
驗證同步傳輸
在釋出伺服器vm1
上操作
#將釋出伺服器vm1的檔案同步到同步伺服器vm2
rsync -avH --port=873 --progress --delete /data/wwwroot/sync/ [email protected]::Sync --password-file=/etc/passwd.txt
#將同步伺服器vm2的檔案同步到釋出伺服器vm1
rsync -avH --port=873 --progress --delete [email protected]::Sync --password-file=/etc/passwd.txt /data/wwwroot/sync
!!!這裡在正式環境上操作一定要注意兩種同步命令的差別,不然會導致檔案刪除
- 刪除/root/下的檔案不會同步刪除/tmp/rsync_bak,除非加入--delete選項
- 檔案訪問時間等屬性、讀寫等許可權、檔案內容等有任何變動,都會被認為修改
- 目標目錄下如果檔案比源目錄還新,則不會同步
- 源路徑的最後是否有斜槓有不同的含義:有斜槓,只是複製目錄中的檔案;沒有斜槓的話,不但要複製目錄中的檔案,還要複製目錄本身
安裝使用inotify
rsync不能實時的去監測、同步資料,雖然它可以通過crontab方式進行觸發同步,但是兩次觸發動作一定會有時間差,這樣就導致了服務端和客戶端資料可能出現不一致,無法在應用故障時完全的恢復資料。基於以上原因,rsync+inotify組合出現了
1、檢視伺服器核心是否支援inotify
#ll /proc/sys/fs/inotify #列出檔案目錄,出現下面的內容,說明伺服器核心支援inotify
-rw-r--r-- 1 root root 0 Mar 7 02:17 max_queued_events
-rw-r--r-- 1 root root 0 Mar 7 02:17 max_user_instances
-rw-r--r-- 1 root root 0 Mar 7 02:17 max_user_watches
注:Linux下支援inotify的核心最小為2.6.13
2、安裝inotify-tools
#wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
#tar zxvf inotify-tools-3.14.tar.gz
#cd inotify-tools-3.14
#./configure --prefix=/usr/local/inotify&& make && make install
3、修改inotify預設引數(inotify預設核心引數值太小)
檢視系統預設引數值
sysctl -a | grep max_queued_events
結果是:fs.inotify.max_queued_events = 16384
sysctl -a | grep max_user_watches
結果是:fs.inotify.max_user_watches = 8192
sysctl -a | grep max_user_instances
結果是:fs.inotify.max_user_instances = 128
#vi /etc/sysctl.conf #新增以下程式碼,修改引數
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535
4、sysctl -p生效,系統重啟後也可以正常工作
引數說明:
max_queued_events:
inotify佇列最大長度,如果值太小,會出現"** Event Queue Overflow **"錯誤,導致監控檔案不準確
max_user_watches:
要同步的檔案包含多少目錄,可以用:find /home_test -type d | wc -l 統計,必須保證max_user_watches值大於統
計結果(這裡/home_test為同步檔案目錄)
max_user_instances:
每個使用者建立inotify例項最大值
inotify-tools
inotify-tools
是為linux下inotify檔案監控工具提供的一套C的開發介面庫函式,同時還提供了一系列的命令列工具,這些工具可以用來監控檔案系統的事件。 inotify-tools是用c編寫的,除了要求核心支援inotify外,不依賴於其他。inotify-tools提供兩種工具,一是inotifywait,它是用來監控檔案或目錄的變化,二是inotifywatch,它是用來統計檔案系統訪問的次數。
rsync組合inotify-tools完成實時同步
這一步的核心其實就是在客戶端建立一個指令碼rsync.sh,適用inotifywait監控本地目錄的變化,觸發rsync將變化的檔案傳輸到遠端備份伺服器上
建立排除在外不同步的檔案列表
排除不需要同步的檔案或目錄有兩種做法:
第一種是inotify監控整個目錄,在rsync中加入排除選項,簡單
第二種是inotify排除部分不監控的目錄,同時rsync中也要加入排除選項,可以減少不必要的網路頻寬和CPU消耗
我們選擇第二種
inotifywait排除
這個操作在客戶端進行,假設/tmp/src/mail/2014/以及/tmp/src/mail/2015/cache/目錄下的所有檔案不用同步,所以不需要監控,/tmp/src/下的其他檔案和目錄都同步
其實對於開啟的臨時檔案,可以不監聽modify時間而改成監聽close_write
inotifywait排除監控目錄有--exclude
# vi /etc/inotify_exclude.lst:
/tmp/src/pdf
@/tmp/src/2014
使用fromfile格式只能用絕對路徑,不能使用諸如*正則表示式去匹配,@表示排除。
如果要排除的格式比較複雜,必須使用正則,那隻能在inotifywait中加入選項
--exclude '(.*/*\.log|.*/*\.swp)$|^/tmp/src/mail/(2014|201.*/cache.*)'
表示排除/tmp/src/mail/以下的2014目錄,和所有201*目錄下的帶cache的檔案或目錄,以及/tmp/src目錄下所有的以.log或.swp結尾的檔案。
rsync排除
使用inotifywait排除監控目錄的情況下,必須同時使用rsync排除對應的目錄,否則只要有觸發同步操作,必然會導致不該同步的目錄也會同步。與inotifywait類似,rsync的同步也有--exclude和--exclude-from兩種寫法
個人還是習慣將要排除同步的目錄解除安裝單獨的檔案列表裡,便於管理。使用--include-from=FILE時,排除檔案列表用絕對路徑,但FILE裡面的內容請用相對路徑,如:
/etc/rsyncd.d/rsync_exclude.lst:
mail/2014/
mail/201*/201*/201*/.??*
mail??*
src/*.html*
src/js/
src/ext3/
src/2014/20140[1-9]/
src/201*/201*/201*/.??*
membermail/
membermail??*
membermail/201*/201*/201*/.??*
排除同步的內容包括,mail下的2014目錄,類似2015/201501/20150101/下的臨時或隱藏檔案等
觸發指令碼如下:(未加入排除選項)
#bin/bash
#rsync auto sync script with inotify
#2018-2-25 mumengyun
current_date=$(date +%Y%m%d_%H%M%S)
source_path=/data/wwwroot/sync/
log_file=/data/wwwlogs/rsync.log
#rsync
rsync_server=192.168.221.128
rsync_user=root
rsync_pwd=/etc/passwd.txt
rsync_module=Sync
#RSYNC_EXCLUDE='/etc/rsyncd.d/rsync_exclude.list'
#rsync client pwd check
if [ ! -e ${rsync_pwd} ];then
echo -e "rsync client passwod file ${rsync_pwd} does not exist!"
exit 0
fi
for ip in $rsync_server
do
/usr/bin/rsync -auvrtzopgP --port=873 --progress --delete --bwlimit=200 --password-file=${rsync_pwd} ${source_path} ${rsync_user}@$ip::${rsync_module}
done
/usr/local/inotify/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f' -e close_write,modify,delete,create,move,attrib ${source_path} | while read file
do
for ip in $rsync_server
do
/usr/bin/rsync -auvrtzopgP --port=873 --progress --delete --bwlimit=200 --password-file=${rsync_pwd} ${source_path} ${rsync_user}@$ip::${rsync_module}
done
done
#inotify log
inotify_fun >> ${log_file} 2>&1 &
--bwlimit=200
用於限制傳輸速率最大200kb,因為在實際應用中發現如果不做速率限制,會導致巨大的CPU消耗