(轉)rsync+inotify實時同步
原文:http://lxw66.blog.51cto.com/5547576/1331048
聲明:rsync inotify 需要逆向思考,當只做rsync不實時同步時,我們一般是從rsync服務端向rsync客戶端同步數據。當需要添加inotify實現實時同步數據時,我們就需要從rsync客戶端向各rsync服務端同步數據,這樣rsync客戶端就變成了master,而rsync服務端就變成了slave。
原理:當web3的本地目錄,也就是需要同步的目錄發生變化時,比如有文件改名、更新、刪除、權限變化,此時就使用inotify命令查找這些變化,進行相應的輪詢工作
服務器地址分配:
Web1:192.168.1.103 (rsync 服務節點)
Web2:192.168.1.104 (rsync 服務節點)
Web3:192.168.1.105 (rsync 內容發布節點、inotify)
同步的目錄是 /mnt ,自動同步順序為 web2,web3——web1。我們將web1 配置成 rsync 的服務器即可。
一、配置 rsync 服務器端(web1)
1.安裝rsync軟件
# yum install rsync
2.手動創建rsync配置文件
# vim /etc/rsyncd.conf
uid = root #全局配置開始,運行rsync的用戶
gid = root #運行rsync的用戶組
usechroot = no #是否讓進程離開工作目錄
max connections = 20 #最大並發數
timeout = 600 #連接超時時間
pid file = /var/run/rsyncd.pid #指定rsync的pid存放路徑
lock file = /var/run/rsync.lock #指定rsync的鎖文件存放路徑
log file = /var/log/rsyncd.log #指定rsync的日誌存放路徑
[web_log] #模塊配置開始
path = /data/web_log/ #需要備份的文件路徑
ignore errors #忽略一些無關的I/O錯誤
read only = false #false為關閉,true表示開啟。表示只讀,不允許上傳文件
writeonly = false #不允許下載
list = false #客戶請求可以使用模塊列表時是否被列出
hosts allow = 192.168.1.0/24 #可以訪問此模塊的主機,*表示任何主機,此處是網段,某個主機直接寫ip
hosts deny = 0.0.0.0/32 #禁止訪問此模塊的主機地址
auth users = backuser #自定義連接該模塊的用戶名,多個用戶用逗號分隔
secrets file = /etc/rsync.password #指定一個包含“用戶名:密碼”格式的文件
3.創建備份目錄
# mkdir -p /data/web_log/
4.建立 rsync 用戶名和密碼文件
# echo"backuser:123" >> /etc/rsync.password
5.為 /etc/rsync.password授權為 600(這個文件的權限必須是 600)
# chmod 600 /etc/rsync.password
6.啟動rsync並添加開啟自動啟動
# /usr/bin/rsync --daemon &
# echo "/usr/bin/rsync --daemon" >> /etc/rc.local
二、配置 rsync 服務器端(web2),和web1配置一樣
# yum install rsync
# vim /etc/rsyncd.conf
uid = root
gid = root
usechroot = no
max connections = 20
timeout = 600
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
[web_log]
path = /data/web_log/ #定義你需要備份的路徑,可以跟web1上不一樣
ignore errors
read only = false
writeonly = false
list = false
hosts allow = *
hosts deny = 0.0.0.0/32
auth users = backuser
secrets file = /etc/rsync.password
# mkdir -p /data/web_log/
# echo "backuser:123" >> /etc/rsync.password
# chmod 600 /etc/rsync.password
# /usr/bin/rsync --daemon &
# echo "/usr/bin/rsync --daemon" >> /etc/rc.local
到此,服務器端配置完成
三、客戶端配置(web3):
1.設置 rsync 客戶端的密碼文件,客戶端只需要設置 rsync 同步的密碼即可,不用設置用戶名
# yum install rsync
# echo "123" > /etc/rsync.password
2.將密碼文件的權限設置成 600(這個文件的權限必須是600)
# chmod 600 /etc/rsync.password
配置 Inotify(在 web3上配置)
1. 安裝 inotify 軟件包
wget http://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
# yum install gcc #如果沒安裝gcc的請安裝,已安裝請跳過此步。
# tar zxf inotify-tools-3.14.tar.gz
# cd inotify-tools-3.14
# ./configure && make && make install
2.在web3上測試一下是否可以同步文件
rsync -vzrtopg --progress /mnt/ [email protected]::web_log --password-file=/etc/rsync.password #上傳文件
rsync -vzrtopg --progress [email protected]::web_log /opt/ --password-file=/etc/rsync.password #下載文件
3. 寫一個腳本來實現,當/mnt/中文件有變化時,讓各rsync服務節點同步數據:
# vim /root/inotify.sh
#!/bin/bash
src=/mnt/ #此文件是rsync客戶端本地文件,需要上傳到各個rsync服務節點
des1=web_log # web1上需要同步的目錄
des2=web_log # web2上需要同步的目錄
host1=192.168.1.103 #rsync服務節點1
host2=192.168.1.104 #rsync服務節點2
user1=backuser #連接rsync使用的用戶名web1上
user2=backuser #連接rsync使用的用戶名web2上
/usr/local/bin/inotifywait -mrq --timefmt ‘%d/%m/%y %H:%M‘ --format ‘%T %w%f‘ -emodify,delete,create,attrib $src | while read file
do
/usr/bin/rsync -vzrtopg --delete --progress $src [email protected]$host1::$des1 --password-file=/etc/rsync.password
/usr/bin/rsync -vzrtopg --delete --progress $src [email protected]$host2::$des2 --password-file=/etc/rsync.password
echo "${files} was rsynced" >> /var/log/rsync.log 2>&1
done
或寫成如下腳本
# vim /root/inotify.sh
#!/bin/bash
/usr/local/bin/inotifywait -mrq --timefmt ‘%d/%m/%y %H:%M‘ --format ‘%T %w%f‘ -e modify,delete,create,attrib /mnt/ | while read file
do
/usr/bin/rsync -vzrtopg --delete --progress /mnt/ [email protected]::web_log --password-file=/etc/rsync.password
/usr/bin/rsync -vzrtopg --delete --progress /mnt/ [email protected]::web_log --password-file=/etc/rsync.password
echo "${files} was rsynced" >> /var/log/rsync.log 2>&1
done
5. 給予執行權限
# chmod +x /root/inotify.sh
# /root/inotify.sh & #在後臺執行
6.最後,將此腳本加入系統自啟動文件
# echo "/root/inotify.sh" >> /etc/rc.local
7.向/mnt/下添加內容,去103上查看是否同步
# ls /data/web_log/
1 11 2 3 4 5 6 7 9
8.編寫監聽inotify進程腳本,防止inotify由於某種原因中斷無法實時同步(如果不需要監聽,此步可以跳過)
# vim /root/inotifyjianting.sh
#!/bin/bash
ps -lef |pgrep inotify &> /dev/null #如果有inotify進程在運行,那麽echo $? 返回值是0,條件為真。否則返回值為非0
if [ -z $? ] ;then #關鍵在$?這個變量 ,它是代表上一條命令執行後的退出狀態,如果是0的話表示成功,非0表示未開啟
echo "inotify runing 正在運行...."
else
/root/inotify.sh &
echo "inotify runing 已運行....."
fi
# chmod +x /root/inotifyjianting.sh
9.添加定時任務計劃
# crontab -e
* * * * * /root/inotifyjianting.sh &> /dev/null
四、rsync如何排除不想同步的目錄或文件(web3)
單個文件排除:比如我不想同步/opt/aa.php文件,直接使用 --exclude “aa.php”
此處只拿一臺web舉例,如有多臺,可自行添加
# vim /root/inotify.sh
#!/bin/bash
src=/opt/
des=web_log
ip=192.168.1.103
/usr/local/bin/inotifywait -mrq --timefmt ‘%d/%m/%y %H:%M‘ --format ‘%T %w%f‘ -emodify,delete,create,attrib $src | while read file
do
rsync-vzrtopg --delete --progress --exclude"aa.php" $src [email protected]$ip::$des--password-file=/etc/rsync.password > /dev/null 2>&1 && echo"$src was rsynced"
echo"${files} was rsynced" >>/tmp/rsync.log 2>&1
done
#ps -elf| pgrep inotify |xargs kill -9 #殺死後臺運行的inotify腳本
殺死後臺運行的inotify腳本
# ps -elf| pgrep inotify |xargs kill -9
啟動腳本
# sh /root/inotify.sh &
設置每一個inotify實例相關聯的watchs的上限,否則傳輸的文件過多會報錯
# echo 30000000 > /proc/sys/fs/inotify/max_user_watches
多個文件或目錄排除:使用--exclude-from=“/root/xx.list”,文件列表,此文件名寫絕對路徑,寫在哪裏都可以,不必就寫在/opt目錄下
創建test目錄
# mkdir/opt/test
修改inotify.sh腳本,添加列表文件
# vim /root/inotify.sh
#!/bin/bash
src=/opt/
des=web_log
ip=192.168.1.103
/usr/local/bin/inotifywait -mrq --timefmt ‘%d/%m/%y %H:%M‘ --format ‘%T %w%f‘ -emodify,delete,create,attrib $src | while read file
do
rsync-vzrtopg --delete --progress --exclude-from="/root/xx.list" $src [email protected]$ip::$des --password-file=/etc/rsync.password > /dev/null2>&1 && echo "$src was rsynced"
echo"${files} was rsynced" >>/tmp/rsync.log 2>&1
done
#ps -elf| pgrep inotify |xargs kill -9 #殺死後臺運行的inotify腳本
編輯要排除文件的列表,即/root/xx.list
編輯要排除的文件列表,其中目錄直接寫目錄名,文本文件寫相對路徑
# vim /root/xx.list #全部相對路徑,也就是從/opt的下一級目錄開始寫,不寫/opt目錄
aw.php #排除/opt/aw.php文件,文件需要從/opt的下一級目錄開始寫,後面的路徑要寫全
bb #排除/opt/bb目錄,目錄無論是/opt的哪個路徑下,只寫目錄名即可
cc #排除/opt/test/cc目錄
test/ww.php #排除/opt/test/aa.php文件
殺死後臺運行的進程
# ps -elf| pgrep inotify |xargs kill -9
執行腳本,在後臺執行
# sh /root/inotify.sh &
設置每一個inotify實例相關聯的watchs的上限,否則傳輸的文件過多會報錯
# echo 30000000 > /proc/sys/fs/inotify/max_user_watches
創建aw.php,然後去web1和web2上分別查看,沒有看到ww.php為成功,其余2個就不在此一一舉例了,道理都一樣
[[email protected]]# touch aw.php
[[email protected]]#/opt/ was rsynced
/opt/ wasrsynced
以是inotify相關參數介紹
腳本相關解釋如下:
--timefmt:
指定時間的輸出格式。
--format:
指定變化文件的詳細信息。
這個腳本的作用就是通過Inotify監控文件目錄的變化,進而觸發rsync進行同步操作。由於這個過程是一種主動觸發操作,是通過系統內核完成的,所以,比起那些遍歷整個目錄的掃描方式來,效率要高很多。
然後我們將此腳本放入後臺運行,輸入如下命令即可:
Sh /root/rsync.sh&
rsync參數說明:
-z 傳輸時壓縮;
-P 傳輸進度;
-v 傳輸時的進度等信息,和-P有點關系,自己試試。可以看文檔;
-e ssh的參數建立起加密的連接。
-u只進行更新,防止本地新文件被重寫,註意兩者機器的時鐘的同時
--progress是指顯示出詳細的進度情況
--delete是指如果服務器端刪除了這一文件,那麽客戶端也相應把文件刪除,保持真正的一致
--password-file=/password/path/file來指定密碼文件,這樣就可以在腳本中使用而無需交互式地輸入驗證密碼了,這裏需要註意的是這份密碼文件權限屬性要設得只有屬主可讀。
inotify 參數說明:
-m 監控
-r 遞歸
-q 靜默模式
-e 指定你要同步的事件
modify 修改
delete 刪除
create 創建
attrib 屬性
以下是rsyncd.conf配置文件參數介紹
全局參數說明
在文件中[modlue]之前的所有參數都是全局參數,當然也可以在全局參數部分定義模塊參數,這時候該參數的值就是所有模塊的默認值。
motd file |
"motd file"參數用來指定一個消息文件,當客戶連接服務器時該文件的內容顯示給客戶,默認是沒有motd文件的。 |
pid file |
指定rsync的pid文件。 |
socket options |
設置socket配置 |
syslog facility |
指定rsync發送日誌消息給syslog時的消息級別,常見的消息級別是:uth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, sys-log, user, uucp, local0, local1, local2, local3,local4, local5, local6和local7。默認值是daemon。 |
Log file |
"log file"指定rsync的日誌文件,而不將日誌發送給syslog。 |
模塊參數說明
在全局參數之後就需要定義一個或多個模塊了,模塊中可以定義以下參數:
紅色的為必須設置;綠色的為涉及到安全問題,應該使用默認配置;其他的為可以不進行設置。
comment |
給模塊指定一個描述,該描述連同模塊名在客戶連接得到模塊列表時顯示給客戶。默認沒有描述定義。 |
path |
指定該模塊的供備份的目錄樹路徑,該參數是必須指定的。 |
use chroot |
如果"use chroot"指定為true,那麽rsync在傳輸文件以前首先chroot到path參數所指定的目錄下。這樣做的原因是實現額外的安全防護,但是缺點是需要以roots權限,並且不能備份指向外部的符號連接所指向的目錄文件。默認情況下chroot值為true。 |
numeric ids |
|
munge symlinks |
使傳進來的文件的鏈接失效,但是可以恢復。只有在use chroot = true, and inside-chroot path是"/"時,為disable,其它默認為enable。防止傳進的鏈接文件指向其不應該指向的文件,從而造成安全漏洞。 |
charset |
字符轉換,如果不設置客戶端—iconv將會被禁止。 |
max connections |
指定該模塊的最大並發連接數量以保護服務器,超過限制的連接請求將被告知隨後再試。默認值是0,也就是沒有限制。 |
max verbosity |
Log信息數量控制,防止出現過多的verbose的log信息,默認為level 1。 |
lock file |
指定支持max connections參數的鎖文件,默認值是/var/run/rsyncd.lock。 |
read only |
該選項設定是否允許客戶上載文件。如果為true那麽任何上載請求都會失敗,如果為false並且服務器目錄讀寫權限允許那麽上載是允許的。默認值為true。 |
write only |
設置是否禁止客戶端下載數據。默認為false。 |
list |
該選項設定當客戶請求可以使用的模塊列表時,該模塊是否應該被列出。如果設置該選項為false,可以創建隱藏的模塊。默認值是true。 |
uid |
該選項指定當該模塊傳輸文件時守護進程應該具有的uid,配合gid選項使用可以確定哪些可以訪問怎麽樣的文件權限,默認值是"nobody"。 |
gid |
該選項指定當該模塊傳輸文件時守護進程應該具有的gid。默認值為"nobody"。 |
fake super |
和客戶端--fake-user的參數相似,=true是無論守護進程啟動權限是否為root,存儲的文件將所有屬性存儲。 |
filter |
文件訪問權限控制。daemon filter chain is built from the "filter", "include from", "include", "exclude from", and "exclude" parameters。 |
exlude |
用來指定多個由空格隔開的多個模式列表,並將其添加到exclude列表中。這等同於在客戶端命令中使用--exclude來指定模式,不過配置文件中指定的exlude模式不會傳遞給客戶端,而僅僅應用於服務器。一個模塊只能指定一個exlude選項,但是可以在模式前面使用"-"和"+"來指定是 exclude還是include。但是需要註意的一點是該選項有一定的安全性問題,客戶很有可能繞過exlude列表,如果希望確保特定的文件不能被訪問,那就最好結合uid/gid選項一起使用。 |
exlude from |
指定一個包含exclude模式的定義的文件名,服務器從該文件中讀取exlude列表定義。 |
include |
用來指定多個由空格隔開的多個rsync並應該exlude的模式列表。這等同於在客戶端命令中使用--include來指定模式,結合include和 exlude可以定義復雜的exlude/include規則。一個模塊只能指定一個include選項,但是可以在模式前面使用"-"和"+"來指定是exclude還是include。 |
include from |
指定一個包含include模式的定義的文件名,服務器從該文件中讀取include列表定義。 |
incoming chmod |
設置“set of comma-separated chmod strings “來修改所有傳入的文件,並且將在所有權限設置完成後執行,除非客戶端指定—perms。格式同chmod一致。 |
outgoing chmod |
同上,在文件傳出前首先運行設置參數。 |
auth users |
該選項指定由空格或逗號分隔的用戶名列表,只有這些用戶才允許連接該模塊。這裏的用戶和系統用戶沒有任何關系。如果"auth users"被設置,那麽客戶端發出對該模塊的連接請求以後會被rsync請求challenged進行驗證身份這裏使用的 challenge/response認證協議。用戶的名和密碼以明文方式存放在"secrets file"選項指定的文件中。默認情況下無需密碼就可以連接模塊(也就是匿名方式)。 |
secrets file |
該選項指定一個包含定義用戶名:密碼對的文件。只有在"auth users"被定義時,該文件才有作用。文件每行包含一個username:passwd對。一般來說密碼最好不要超過8個字符。沒有默認的 secures file名,需要限式指定一個。(例如:/etc/rsyncd.secrets) |
strict modes |
該選項指定是否監測密碼文件的權限,如果該選項值為true那麽密碼文件只能被rsync服務器運行身份的用戶訪問,其他任何用戶不可以訪問該文件。默認值為true。 |
hosts allow |
該選項指定哪些IP的客戶允許連接該模塊。客戶模式定義可以是以下形式: 1 xxx.xxx.xxx.xxx,客戶主機只有完全匹配該IP才允許訪問。例如:192.167.0.1 2 a.b.c.d/n,屬於該網絡的客戶都允許連接該模塊。例如:192.168.0.0/24 3 a.b.c.d/e.f.g.h,屬於該網絡的客戶都允許連接該模塊。例如:192.168.0.0/255.255.255.0 4 一個主機名,客戶主機只有擁有該主機名才允許訪問,例如:backup.linuxaid.com.cn。 5 *.linuxaid.com.cn,所有屬於該域的主機都允許。 默認是允許所有主機連接。 |
hosts deny |
指定不允許連接rsync服務器的機器,可以使用hosts allow的定義方式來進行定義。默認是沒有hosts deny定義。 |
ignore errors |
指定rsyncd在判斷是否運行傳輸時的刪除操作時忽略server上的IP錯誤,一般來說rsync在出現IO錯誤時將將跳過--delete操作,以防止因為暫時的資源不足或其它IO錯誤導致的嚴重問題。 |
ignore nonreadable |
指定rysnc服務器完全忽略那些用戶沒有訪問權限的文件。這對於在需要備份的目錄中有些文件是不應該被備份者得到的情況是有意義的。應該設置為true。 |
transfer logging |
使rsync服務器使用ftp格式的文件來記錄下載和上載操作在自己單獨的日誌中。 |
log format |
通過該選項用戶在使用transfer logging可以自己定制日誌文件的字段。其格式是一個包含格式定義符的字符串,可以使用的格式定義符如下所示: %a 遠程IP地址;%b 實際傳輸的字節數;%B the permission bits of the file (e.g. rwxrwxrwt) ;%l 文件長度字符數;%c 當發送文件時,該字段記錄該文件的校驗碼;%f 文件名;%G the gid of the file (decimal) or "DEFAULT" ;%h 遠程主機名; %p 該次rsync會話的進程id;%o 操作類型:"send"或"recv"; %P 模塊路徑; %m 模塊名;%i an itemized list of what is being updated;%U the uid of the file (decimal); %t 當前時間;%u 認證的用戶名(匿名時是null); 默認log格式為:"%o %h [%a] %m (%u) %f %l",一般來說,在每行的頭上會添加"%t [%p] "。在源代碼中同時發布有一個叫rsyncstats的perl腳本程序來統計這種格式的日誌文件。 |
timeout |
通過該選項可以覆蓋客戶指定的IP超時時間。通過該選項可以確保rsync服務器不會永遠等待一個崩潰的客戶。超時單位為秒鐘,0表示沒有超時定義,這也是默認值。對於匿名rsync服務器來說,一個理想的數字是600。 |
refuse options |
通過該選項可以定義一些不允許客戶對該模塊使用的命令參數列表。這裏必須使用命令全名,而不能是簡稱。但發生拒絕某個命令的情況時服務器將報告錯誤信息然後退出。如果要防止使用壓縮,應該是:"dont compress = *"。 |
dont compress |
用來指定那些不進行壓縮處理再傳輸的文件,默認值是 *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz |
pre-xfer exec, post-xfer exec |
在傳輸前指定要運行的命令行,如果命令運行失敗,將停止傳輸。 註意:命令行將使用啟動守護進程的用戶權限執行! |
syslog facility |
指定rsync發送日誌消息給syslog時的消息級別,常見的消息級別是:uth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, sys-log, user, uucp, local0, local1, local2, local3,local4, local5, local6和local7。默認值是daemon。 |
Log file |
"log file"指定rsync的日誌文件,而不將日誌發送給syslog。 |
(轉)rsync+inotify實時同步