Linux下同步工具inotify+rsync使用详解
1. rsync
1.1 什么是rsync
rsync是一個(gè)遠(yuǎn)程數(shù)據(jù)同步工具,可通過LAN/WAN快速同步多臺(tái)主機(jī)間的文件。它使用所謂的“Rsync演算法”來使本地和遠(yuǎn)程兩個(gè)主機(jī)之間的文件達(dá)到同步,這個(gè)算法只傳送兩個(gè)文件的不同部分,而不是每次都整份傳送,因此速度相當(dāng)快。所以通常可以作為備份工具來使用。
運(yùn)行Rsync server的機(jī)器也叫backup server,一個(gè)Rsync server可同時(shí)備份多個(gè)client的數(shù)據(jù);也可以多個(gè)Rsync server備份一個(gè)client的數(shù)據(jù)。Rsync可以搭配ssh甚至使用daemon模式。Rsync server會(huì)打開一個(gè)873的服務(wù)通道(port),等待對(duì)方rsync連接。連接時(shí),Rsync server會(huì)檢查口令是否相符,若通過口令查核,則可以開始進(jìn)行文件傳輸。第一次連通完成時(shí),會(huì)把整份文件傳輸一次,下一次就只傳送二個(gè)文件之間不同的部份。
基本特點(diǎn):
命令語(yǔ)法:
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]
對(duì)應(yīng)于以上六種命令格式,我們可以總結(jié)rsync有2種不同的工作模式:
- shell模式:使用遠(yuǎn)程shell程序(如ssh或rsh)進(jìn)行連接。當(dāng)源路徑或目的路徑的主機(jī)名后面包含一個(gè)冒號(hào)分隔符時(shí)使用這種模式,rsync安裝完成后就可以直接使用了,無所謂啟動(dòng)。(目前沒有嘗試過這個(gè)方法)
- daemon模式:使用TCP直接連接rsync daemon。當(dāng)源路徑或目的路徑的主機(jī)名后面包含兩個(gè)冒號(hào),或使用rsync://URL時(shí)使用這種模式,無需遠(yuǎn)程shell,但必須在一臺(tái)機(jī)器上啟動(dòng)rsync daemon,默認(rèn)端口873,這里可以通過rsync --daemon使用獨(dú)立進(jìn)程的方式,或者通過xinetd超級(jí)進(jìn)程來管理rsync后臺(tái)進(jìn)程。
當(dāng)rsync作為daemon運(yùn)行時(shí),它需要一個(gè)用戶身份。如果你希望啟用chroot,則必須以root的身份來運(yùn)行daemon,監(jiān)聽端口,或設(shè)定文件屬主;如果不啟用chroot,也可以不使用root用戶來運(yùn)行daemon,但該用戶必須對(duì)相應(yīng)的模塊擁有讀寫數(shù)據(jù)、日志和lock file的權(quán)限。當(dāng)rsync以daemon模式運(yùn)行時(shí),它還需要一個(gè)配置文件——rsyncd.conf。修改這個(gè)配置后不必重啟rsync daemon,因?yàn)槊恳淮蔚腸lient連接都會(huì)去重新讀取該文件。
我們一般把DEST遠(yuǎn)程服務(wù)器端成為rsync Server,運(yùn)行rsync命令的一端SRC稱為Client。
安裝:
rsync在CentOS6上默認(rèn)已經(jīng)安裝,如果沒有則可以使用yum install rsync -y,服務(wù)端和客戶端是同一個(gè)安裝包。
1.2 同步測(cè)試
關(guān)于rsync命令的諸多選項(xiàng)說明,見另外一篇文章rsync與inotifywait命令和配置選項(xiàng)說明。
1.2.1 本機(jī)文件夾同步
會(huì)看到從/root/傳輸文件到/tmp/rsync_bak/的列表和速率,再運(yùn)行一次會(huì)看到sending incremental file list下沒有復(fù)制的內(nèi)容,可以在/root/下touch某一個(gè)文件再運(yùn)行看到只同步了修改過的文件。
上面需要考慮以下問題:
- 刪除/root/下的文件不會(huì)同步刪除/tmp/rsync_bak,除非加入--delete選項(xiàng)
- 文件訪問時(shí)間等屬性、讀寫等權(quán)限、文件內(nèi)容等有任何變動(dòng),都會(huì)被認(rèn)為修改
- 目標(biāo)目錄下如果文件比源目錄還新,則不會(huì)同步
- 源路徑的最后是否有斜杠有不同的含義:有斜杠,只是復(fù)制目錄中的文件;沒有斜杠的話,不但要復(fù)制目錄中的文件,還要復(fù)制目錄本身
1.3 同步到遠(yuǎn)程服務(wù)器
在服務(wù)器間rsync傳輸文件,需要有一個(gè)是開著rsync的服務(wù),而這一服務(wù)需要兩個(gè)配置文件,說明當(dāng)前運(yùn)行的用戶名和用戶組,這個(gè)用戶名和用戶組在改變文件權(quán)限和相關(guān)內(nèi)容的時(shí)候有用,否則有時(shí)候會(huì)出現(xiàn)提示權(quán)限問題。配置文件也說明了模塊、模塊化管理服務(wù)的安全性,每個(gè)模塊的名稱都是自己定義的,可以添加用戶名密碼驗(yàn)證,也可以驗(yàn)證IP,設(shè)置目錄是否可寫等,不同模塊用于同步不同需求的目錄。
1.3.1 服務(wù)端配置文件
** /etc/rsyncd.conf: **
[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
" title="" data-original-title=“復(fù)制”>
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]開始定義一個(gè)模塊,指定要同步的目錄(接收)path,授權(quán)用戶,密碼文件,允許哪臺(tái)服務(wù)器IP同步(發(fā)送)等。關(guān)于配置文件中選項(xiàng)的詳細(xì)說明依然參考rsync與inotifywait命令和配置選項(xiàng)說明。
經(jīng)測(cè)試,上述配置文件每行后面不能使用#來來注釋
** /etc/rsyncd.secrets: **
sean:passw0rd一行一個(gè)用戶,用戶名:密碼。請(qǐng)注意這里的用戶名和密碼與操作系統(tǒng)的用戶名密碼無關(guān),可以隨意指定,與/etc/rsyncd.conf中的auth users對(duì)應(yīng)。
修改權(quán)限:chmod 600 /etc/rsyncd.d/rsync_server.pwd。
1.3.2 服務(wù)器啟動(dòng)rsync后臺(tái)服務(wù)
修改/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 = noflags = IPv6socket_type = streamwait = nouser = rootserver = /usr/bin/rsyncserver_args = --daemonlog_on_failure += USERID }執(zhí)行service xinetd restart會(huì)一起重啟rsync后臺(tái)進(jìn)程,默認(rèn)使用配置文件/etc/rsyncd.conf。也可以使用/usr/bin/rsync --daemon --config=/etc/rsyncd.conf。
為了以防rsync寫入過多的無用日志到/var/log/message(容易塞滿從而錯(cuò)過重要的信息),建議注釋掉/etc/xinetd.conf的success:
如果使用了防火墻,要添加允許IP到873端口的規(guī)則。
建議關(guān)閉selinux,可能會(huì)由于強(qiáng)訪問控制導(dǎo)致同步報(bào)錯(cuò)。
1.3.3 客戶端測(cè)試同步
單向同步時(shí),客戶端只需要一個(gè)包含密碼的文件。
/etc/rsync_client.pwd:
chmod 600 /etc/rsync_client.pwd
命令:
將本地/root/目錄同步到遠(yuǎn)程172.29.88.223的/tmp/rsync_bak2目錄(module_test指定):
當(dāng)然你也可以將遠(yuǎn)程的/tmp/rsync_bak2目錄同步到本地目錄/root/tmp:
/usr/bin/rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd sean@172.29.88.223::module_test /root/從上面兩個(gè)命令可以看到,其實(shí)這里的服務(wù)器與客戶端的概念是很模糊的,rsync daemon都運(yùn)行在遠(yuǎn)程172.29.88.223上,第一條命令是本地主動(dòng)推送目錄到遠(yuǎn)程,遠(yuǎn)程服務(wù)器是用來備份的;第二條命令是本地主動(dòng)向遠(yuǎn)程索取文件,本地服務(wù)器用來備份,也可以認(rèn)為是本地服務(wù)器恢復(fù)的一個(gè)過程。
1.4 rsync不足
與傳統(tǒng)的cp、tar備份方式相比,rsync具有安全性高、備份迅速、支持增量備份等優(yōu)點(diǎn),通過rsync可以解決對(duì)實(shí)時(shí)性要求不高的數(shù)據(jù)備份需求,例如定期的備份文件服務(wù)器數(shù)據(jù)到遠(yuǎn)端服務(wù)器,對(duì)本地磁盤定期做數(shù)據(jù)鏡像等。
隨著應(yīng)用系統(tǒng)規(guī)模的不斷擴(kuò)大,對(duì)數(shù)據(jù)的安全性和可靠性也提出的更好的要求,rsync在高端業(yè)務(wù)系統(tǒng)中也逐漸暴露出了很多不足,首先,rsync同步數(shù)據(jù)時(shí),需要掃描所有文件后進(jìn)行比對(duì),進(jìn)行差量傳輸。如果文件數(shù)量達(dá)到了百萬甚至千萬量級(jí),掃描所有文件將是非常耗時(shí)的。而且正在發(fā)生變化的往往是其中很少的一部分,這是非常低效的方式。其次,rsync不能實(shí)時(shí)的去監(jiān)測(cè)、同步數(shù)據(jù),雖然它可以通過crontab方式進(jìn)行觸發(fā)同步,但是兩次觸發(fā)動(dòng)作一定會(huì)有時(shí)間差,這樣就導(dǎo)致了服務(wù)端和客戶端數(shù)據(jù)可能出現(xiàn)不一致,無法在應(yīng)用故障時(shí)完全的恢復(fù)數(shù)據(jù)。基于以上原因,rsync+inotify組合出現(xiàn)了!
2. inotify-tools
2.1 什么是inotify
inotify是一種強(qiáng)大的、細(xì)粒度的、異步的文件系統(tǒng)事件監(jiān)控機(jī)制,Linux內(nèi)核從2.6.13開始引入,允許監(jiān)控程序打開一個(gè)獨(dú)立文件描述符,并針對(duì)事件集監(jiān)控一個(gè)或者多個(gè)文件,例如打開、關(guān)閉、移動(dòng)/重命名、刪除、創(chuàng)建或者改變屬性。
CentOS6自然已經(jīng)支持:
使用ll /proc/sys/fs/inotify命令,是否有以下三條信息輸出,如果沒有表示不支持。
- /proc/sys/fs/inotify/max_queued_evnets表示調(diào)用inotify_init時(shí)分配給inotify instance中可排隊(duì)的event的數(shù)目的最大值,超出這個(gè)值的事件被丟棄,但會(huì)觸發(fā)IN_Q_OVERFLOW事件。
- /proc/sys/fs/inotify/max_user_instances表示每一個(gè)real user ID可創(chuàng)建的inotify instatnces的數(shù)量上限。
- /proc/sys/fs/inotify/max_user_watches表示每個(gè)inotify instatnces可監(jiān)控的最大目錄數(shù)量。如果監(jiān)控的文件數(shù)目巨大,需要根據(jù)情況,適當(dāng)增加此值的大小。
inotify-tools:
inotify-tools是為linux下inotify文件監(jiān)控工具提供的一套C的開發(fā)接口庫(kù)函數(shù),同時(shí)還提供了一系列的命令行工具,這些工具可以用來監(jiān)控文件系統(tǒng)的事件。 inotify-tools是用c編寫的,除了要求內(nèi)核支持inotify外,不依賴于其他。inotify-tools提供兩種工具,一是inotifywait,它是用來監(jiān)控文件或目錄的變化,二是inotifywatch,它是用來統(tǒng)計(jì)文件系統(tǒng)訪問的次數(shù)。
下載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_642.2 inotifywait使用示例
監(jiān)控/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/上面的命令表示,持續(xù)監(jiān)聽/root/tmp目錄及其子目錄的文件變化,監(jiān)聽事件包括文件被修改、刪除、創(chuàng)建、移動(dòng)、屬性更改,顯示到屏幕。執(zhí)行完上面的命令后,在/root/tmp下創(chuàng)建或修改文件都會(huì)有信息輸出:
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完成實(shí)時(shí)同步
這一步的核心其實(shí)就是在客戶端創(chuàng)建一個(gè)腳本rsync.sh,適用inotifywait監(jiān)控本地目錄的變化,觸發(fā)rsync將變化的文件傳輸?shù)竭h(yuǎn)程備份服務(wù)器上。為了更接近實(shí)戰(zhàn),我們要求一部分子目錄不同步,如/root/tmp/log和臨時(shí)文件。
3.1 創(chuàng)建排除在外不同步的文件列表
排除不需要同步的文件或目錄有兩種做法,第一種是inotify監(jiān)控整個(gè)目錄,在rsync中加入排除選項(xiàng),簡(jiǎn)單;第二種是inotify排除部分不監(jiān)控的目錄,同時(shí)rsync中也要加入排除選項(xiàng),可以減少不必要的網(wǎng)絡(luò)帶寬和CPU消耗。我們選擇第二種。
3.1.1 inotifywait排除
這個(gè)操作在客戶端進(jìn)行,假設(shè)/tmp/src/mail/2014/以及/tmp/src/mail/2015/cache/目錄下的所有文件不用同步,所以不需要監(jiān)控,/tmp/src/下的其他文件和目錄都同步。(其實(shí)對(duì)于打開的臨時(shí)文件,可以不監(jiān)聽modify時(shí)間而改成監(jiān)聽close_write)
inotifywait排除監(jiān)控目錄有--exclude <pattern>和--fromfile <file>兩種格式,并且可以同時(shí)使用,但主要前者可以用正則,而后者只能是具體的目錄或文件。
# vi /etc/inotify_exclude.lst: /tmp/src/pdf使用fromfile格式只能用絕對(duì)路徑,不能使用諸如*正則表達(dá)式去匹配,@表示排除。
如果要排除的格式比較復(fù)雜,必須使用正則,那只能在inotifywait中加入選項(xiàng),如--exclude '(.*/*\.log|.*/*\.swp)$|^/tmp/src/mail/(2014|201.*/cache.*)',表示排除/tmp/src/mail/以下的2014目錄,和所有201*目錄下的帶cache的文件或目錄,以及/tmp/src目錄下所有的以.log或.swp結(jié)尾的文件。
3.1.2 rsync排除
使用inotifywait排除監(jiān)控目錄的情況下,必須同時(shí)使用rsync排除對(duì)應(yīng)的目錄,否則只要有觸發(fā)同步操作,必然會(huì)導(dǎo)致不該同步的目錄也會(huì)同步。與inotifywait類似,rsync的同步也有--exclude和--exclude-from兩種寫法。
個(gè)人還是習(xí)慣將要排除同步的目錄卸載單獨(dú)的文件列表里,便于管理。使用--include-from=FILE時(shí),排除文件列表用絕對(duì)路徑,但FILE里面的內(nèi)容請(qǐng)用相對(duì)路徑,如:
/etc/rsyncd.d/rsync_exclude.lst:
排除同步的內(nèi)容包括,mail下的2014目錄,類似2015/201501/20150101/下的臨時(shí)或隱藏文件,等。
3.2 客戶端同步到遠(yuǎn)程的腳本rsync.sh
下面是一個(gè)完整的同步腳本,請(qǐng)根據(jù)需要進(jìn)行裁剪,rsync.sh:
#rsync
rsync_server=172.29.88.223
rsync_user=sean
rsync_pwd=/etc/rsync_client.pwd
rsync_module=module_test
INOTIFY_EXCLUDE=’(./.log|./.swp)$|^/tmp/src/mail/(2014|20.*/.che.)’
RSYNC_EXCLUDE=’/etc/rsyncd.d/rsync_exclude.lst’
#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’
–exclude ${INOTIFY_EXCLUDE} -e modify,delete,create,move,attrib KaTeX parse error: Expected 'EOF', got '\ ' at position 15: {source_path} \? ? | whi…{RSYNC_EXCLUDE} --progress --bwlimit=200 --password-file=${rsync_pwd} ${source_path} rsyncuser@{rsync_user}@rsyncu?ser@{rsync_server}:?{rsync_module}
done
}
#inotify log
inotify_fun >> KaTeX parse error: Expected 'EOF', got '&' at position 14: {log_file} 2>&?amp;1 & " t…(date +%Y%m%d_%H%M%S)
source_path=/tmp/src/
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
INOTIFY_EXCLUDE=’(./.log|./.swp)$|^/tmp/src/mail/(2014|20.*/.che.)’
RSYNC_EXCLUDE=’/etc/rsyncd.d/rsync_exclude.lst’
#rsync client pwd check
if [ ! -e rsyncpwd</span>];<spanclass="hljs?keyword">then</span><spanclass="hljs?builtin">echo</span>?e<spanclass="hljs?string">"rsyncclientpasswodfile<spanclass="hljs?variable">{rsync_pwd}</span> ];<span class="hljs-keyword">then</span> <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"rsync client passwod file <span class="hljs-variable">rsyncp?wd</span>];<spanclass="hljs?keyword">then</span><spanclass="hljs?builti?n">echo</span>?e<spanclass="hljs?string">"rsyncclientpasswodfile<spanclass="hljs?variable">{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’
–exclude INOTIFYEXCLUDE</span>?emodify,delete,create,move,attrib<spanclass="hljs?variable">{INOTIFY_EXCLUDE}</span> -e modify,delete,create,move,attrib <span class="hljs-variable">INOTIFYE?XCLUDE</span>?emodify,delete,create,move,attrib<spanclass="hljs?variable">{source_path}
| while read file
do
/usr/bin/rsync -auvrtzopgP --exclude-from=RSYNCEXCLUDE</span>??progress??bwlimit=200??password?file=<spanclass="hljs?variable">{RSYNC_EXCLUDE}</span> --progress --bwlimit=200 --password-file=<span class="hljs-variable">RSYNCE?XCLUDE</span>??progress??bwlimit=200??password?file=<spanclass="hljs?variable">{rsync_pwd} sourcepath</span><spanclass="hljs?variable">{source_path}</span> <span class="hljs-variable">sourcep?ath</span><spanclass="hljs?variable">{rsync_user}@rsyncserver</span>::<spanclass="hljs?variable">{rsync_server}</span>::<span class="hljs-variable">rsyncs?erver</span>::<spanclass="hljs?variable">{rsync_module}
done
}
#inotify log
inotify_fun >> ${log_file} 2>&1 &
--bwlimit=200用于限制傳輸速率最大200kb,因?yàn)樵趯?shí)際應(yīng)用中發(fā)現(xiàn)如果不做速率限制,會(huì)導(dǎo)致巨大的CPU消耗。
在客戶端運(yùn)行腳本# ./rsync.sh即可實(shí)時(shí)同步目錄。
其他功能:雙向同步、sersync2實(shí)時(shí)同步多遠(yuǎn)程服務(wù)器
參考
- How Rsync Works
- 用 inotify 監(jiān)控 Linux 文件系統(tǒng)事件
- Inotify: 高效、實(shí)時(shí)的Linux文件系統(tǒng)事件監(jiān)控框架
- rsync 的核心算法
原文鏈接地址:http://seanlook.com/2014/12/12/rsync_inotify_setup/
總結(jié)
以上是生活随笔為你收集整理的Linux下同步工具inotify+rsync使用详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SSE,MSE,RMSE,R-squar
- 下一篇: Linux下的各种文件阅读器