Rsync(remote sync)是UNIX及類UNIX平台下一款神奇的數據鏡像備份軟件,它不像FTP或其他文件傳輸服務那樣需要進行全備份,Rsync可以根據數據的變化進行差異備份,從而減少數據流量,提高工作效率。可以使用它進行本地數據或遠程數據的復制,Rsync可以使用SSH安全隧道進行加密數據傳輸。Rsync服務器端定義源數據,Rsync客戶端僅在源數據發生改變后才會從服務器上實際復制數據至本地,如果源數據在服務器端被刪除,則客戶端數據也會被刪除,以確保主機之間的數據是同步的。Rsync使用TCP 873端口。
一、搭建Rsync服務器
為了檢驗Rsync服務配置的效果,需要使用兩台Linux主機(一台充當Rsync服務器,另一台充當Rsync客戶端),下表是它們所使用的操作系統以及IP地址。
兩台Linux主機所使用的操作系統以及IP地址 |
||
主機名稱 | 操作系統 | IP地址 |
Rsync服務端 | CentOS7.5 | 192.168.5.12 |
Rsync客戶端 | CentOS7.5 | 192.168.5.5 |
# yum安裝rsync
yum install rsync
# 啟動rsync
systemctl start rsyncd
# 允許開機自啟動
systemctl enable rsyncd
# 檢查是否已經成功啟動
netstat -lnp |grep 873
因為Rsync是Andrew Tridgell(Samba的作者)與Paul Mackerras合作開發的軟件,所以Rsync配置文件與Samba配置文件比較相似。Rsync主要分為三個配置文件,分別是:rsyncd.conf(主配置文件)、rsyncd.secrets(密碼文件)和rsyncd.motd(服務器信息文件)。
下面的案例將演示如何共享/common目錄,為此,需要創建/common目錄,並復制一些測試文件存放在該目錄下
mkdir /common
cp /etc/init.d/* /common/
進入Rsync的主配置文件
vim /etc/rsyncd.conf
默認配置文件如下圖所示:
下面將進行Rsync配置:
#/etc/rsyncd.conf #設置服務器信息提示文件名稱,在該文件中編寫提示信息 motd file=/etc/rsyncd.motd #開啟Rsync數據傳輸日志功能 transfer logging=yes #設置日志文件名稱,可以通過1og format參數設置日志格式 log file=/var/1og/rsyncd.1og #設置Rsync進程號保存文件名稱 pid file=/var/run/rsyncd.pid #設置鎖文件名稱 lock file=/var/run/rsync.lock #設置服務器監聽的端口號,默認為873 port=873 #設置服務器所監聽網卡接口的IP地址,這里服務器IP地址為192.168.5.12 address=192.168.5.12 #設置進行數據傳輸時所使用的賬戶名稱或ID號,默認使用nobody uid=nobody #設置進行數據傳輸時所使用的組名稱或GID號,默認使用nobody gid=nobody #設置user chroot為yes后,rsync會首先進行chroot設置,將根映射到path參數路徑下,對客戶端而言,系統的根就是path參數所指定的路徑。但這樣做需要root權限,並且在同步符號連 接資料時僅會同步名稱,而內容將不會同步。 use chroot=no #是否允許客戶端上傳數據,這里設置為只讀。 read only=yes #設置並發連接數,0代表無限制。超出並發數后,如果依然有客戶端連接請求,則將會收到稍后重試的提示消息 max connections=10 #模塊,Rsync通過模塊定義同步的目錄,模塊以[name]的形式定義,這與Samba定義共享目錄是一樣的效果。在Rsync中也可以定義多個模塊 [common] #comment定義注釋說明字串 comment=Web content #同步目錄的真實路徑通過path指定 path=/common #忽略一些IO錯誤 ignore errors #exclude可以指定例外的目錄,即將common目錄下的某個目錄設置為不同步數據 #exclude=test/ #設置允許連接服務器的賬戶,賬戶可以是系統中不存在的用戶 auth users=zhangsan,wangwu #設置密碼驗證文件名稱,注意該文件的權限要求為只讀,建議權限為600,僅在設置auth users參數后有效 secrets file=/etc/rsyncd.secrets #設置允許哪些主機可以同步數據,可以是單個IP,也可以是網段,多個IP與網段之間使用空格分隔 hosts allow=192.168.5.0/255.255.255.0 #設置拒絕所有(除hosts allow定義的主機外) hosts deny=* #客戶端請求顯示模塊列表時,本模塊名稱是否顯示,默認為true list=false
接下來,通過echo的方式創建密碼文件/etc/rsyncd.secrets,在該文件中輸入兩個賬戶:zhangsan賬戶的密碼是123,wangwu賬戶的密碼是456。需要注意的是,密碼文件不可以對所有的人開放可讀權限,為了安全,建議設置權限為600。創建服務器提示信息文件並向該文件中導入歡迎詞。
echo "zhangsan:123" > /etc/rsyncd.secrets
echo "wangwu:456" >> /etc/rsyncd.secrets
chmod 600 /etc/rsyncd.secrets
echo "Welcome to access" > /etc/rsyncd.motd
systemctl restart rsyncd
iptables -F # 清空防火牆規則鏈
二、客戶端同步數據
在客戶端主機中同樣是使用rsync命令進行初始化數據傳輸,使用同樣的程序。
yum install rsync
rsync -vzrtopg --progress zhangsan@192.168.5.12::common /test
rsync命令的描述和用法如下:
描述:一個快速、多功能的遠程(或本地)數據復制工具。
用法:下表較全面地介紹了rsync的語法格式,SRC表示源路徑,DEST表示目標路徑。
本地復制 | |
rsync [選項] SRC... [DEST] |
|
通過遠程shell復制 | |
下載數據 | rsync [選項] [USER@]HOST:SRC…[DEST] |
上傳數據 | rsync [選項] SRC... [USER@]HOST:DEST |
通過rsync遠程復制 | |
下載數據 | Rsync [選項] [USER@]HOST::SRC…[DEST] |
Rsync [選項]rsync://[USER@]HOST[:PORT]/SRC…[DEST] |
|
上傳數據 | Rsync [選項]SRC…[USER@]HOST::DEST |
Rsync [選項]SRC...rsync://[USER@]HOST[:PORT]/DEST |
選項:
-v,--verbose | 顯示詳細信息 |
-q,--quiet | 靜默模式,無錯誤信息 |
-a,--archive | 歸檔模式,主要保留文件屬性,等同於-rlptgoD |
-r,--recursive | 遞歸 |
-b,--backup | 如果目標路徑已經存在同名文件,將舊的文件重命名為~filename,可以使用--suffix指定不同的備份前綴 |
--back-dir | 將備份文件保存至指定目錄 |
--suffix | 指定備份文件前綴 |
-u,--update | 如果目標地址中的文件比將要下載的文件新,則不執行同步,也就是說,不會用舊的文件覆蓋新的文件 |
-l,--links | 保留符號鏈接 |
-p,--perms | 保留文件權限屬性 |
-H,--hard-links | 保留硬鏈接 |
-A,--acls | 保留ACL權限 |
-X,--xattrs | 保留文件附加屬性 |
-o,--owner | 保留文件所有者屬性 |
-g,--group | 保留文件所屬組屬性 |
--devices | 保留設備文件 |
--specials | 保留特殊文件 |
-D | 等同於-devices-specials |
-t | 保留修改時間屬性 |
-W,--whole-file | 不做增量檢查,直接復制全部文件 |
-e,--rsh=COMMAND | 指定遠程shell |
--existing | 僅同步目標路徑中已經有的文件,不下載源路徑下新的文件 |
--delete | 刪除那些僅在目標路徑中存在的文件(源路徑中不存在) |
-z,--compress | 傳輸過程中對數據進行壓縮 |
--include=PATTERN | 匹配不排除的文件 |
--exclude=PATTERN | 匹配需要排除的文件 |
--progress | 顯示數據傳輸的進度信息 |
--partial | 保留因故障未傳輸完成的文件 |
-P | 等同於--progress-partial |
--delete | 刪除那些目標位置有而原始位置沒有的文件 |
--password-file=FILE | 指定密碼文件,將密碼寫入文件,實現非交互式數據同步 |
--list-only | 僅列出服務器模塊列表,需要rsync服務器設置list=true |
實例:
1、從192.168.5.12主機上以遞歸方式將/common目錄復制至本機/demo目錄
rsync -avz 192.168.5.12:/common /demo
注意:需要輸入root賬戶的密碼
2、從192.168.5.12主機上以遞歸方式將/common/目錄下的所有內容復制至本機/demo目錄,但在/demo目錄下不會創建common目錄
rsync -avz 192.168.5.12:/common/ /demo
3、將本機當前目錄下的以.c結尾的文件復制至192.168.5.12主機的common目錄下
rsync -t *.c 192.168.5.12:/common
這里遇到如下圖的錯誤:
解決方法:
執行一下:ssh -o StrictHostKeyChecking=no 192.168.5.12
再重新執行 rsync -t *.c 192.168.5.12:/common,就好了
4、將本機/demo/目錄復制至本機/dest目錄
rsync -avz /demo/ /dest
5、使用zhangsan賬戶連接遠程192.168.5.12主機的rsync進程,將common模塊定義的path路徑下載至本地/demo目錄。
rsync -avz zhangsan@192.168.5.12::common /demo
6、匿名下載192.168.5.12服務器的common模塊至本地/demo目錄
rsync -avz 192.168.5.12::common /demo
注意,執行這條命令前需要把 /etc/rsyncd.conf 配置文件里的 auth users=zhangsan,wangwu 注釋掉,才能成功,若不注釋,會提示輸入密碼
7、顯示192.168.5.12服務器所有的模塊名稱,需要服務器端配置list=true才會顯示
rsync --list-only zhangsan@192.168.5.12::
8、客戶端主機每次連接服務器都需要輸入密碼顯得非常麻煩,為此,我們可以創建密碼文件rsync.pass,在該文件中僅包含密碼,最后使用rsync命令的--password-file參數指定密碼文件,就可以省去每次輸入密碼的煩惱。
echo "123" > rsync.pass
chmod 600 rsync.pass
rsync -avz --delete --password-file=rsync.pass zhangsan@192.168.5.12::common /demo
注意權限必須設置為600,否則會報以下錯誤:
三、Rsync+lnotify實現文件自動同步
如果僅使用Rsync進行數據同步,只能滿足企業對數據實時性要求不高的環境,即使使用計划任務也僅可以實現定期的數據同步。而且使用Rsync在進行數據同步前需要對所有的文件進行對比,然后進行差異數據同步,然而我們的數據可能只是1TB數據中的1KB數據發生了改變,在不知道什么時候會發生數據改變的情況下,為了同步1KB的數據,我們需要不停地進行Rsync連接,對比客戶端與服務器之間的數據差異,這樣的機制在當前大數據時代背景下是低效的。往往數據的變化隨時都有可能發生,如果多台主機之間要求當數據發生變化后進行實時同步,就需要結合Inotify(inode notify)工具。目前Inotify 已經被集成到Linux內核中(Linux從2.6.13版本的內核以后全部集成了Inotify功能),Inotify為用戶態應用程序提供了文件系統事件通告機制,比如,當發生文件的訪問、修改以及刪除等事件時,可以立刻通告給用戶態應用程序,通過Inotify可以實時了解文件系統發生的所有變化。
# 查看當前系統是否支持inotify
ll /proc/sys/fs/inotify/
解釋:
/proc/sys/fs/inotify/max_queued_events
# 表示調用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可監控的最大目錄數量。如果監控的文件數目巨大,需要根據情況,適當增加此值的大小。
例如:echo 30000000 > /proc/sys/fs/inotify/max_user_watches
下表是Inotify可以監控的部分常見文件系統事件。
時間名稱 | 描述 |
IN_ACCESS | 文件訪問事件 |
IN_MODIFY | 文件修改事件 |
IN_ATTRIB | 文件屬性修改事件 |
IN_OPEN | 文件打開事件 |
IN_CLOSE_WRITE | 可寫文件被關閉事件 |
IN_CLOSE_NOWRITE | 不可寫文件被關閉事件 |
IN_MOVED_FROM IN_MOVED_TO |
文件移動或重命名事件 |
IN_DELETE | 文件或目錄刪除事件 |
IN_CREATE | 文件或目錄創建事件 |
IN_DELETE_SELF | 自刪除事件 |
利用Inotify的這種事件通知機制,用戶態的應用程序就可以實時監控文件系統的變化,然而Inotify僅是內核提供的一種系統功能,用戶如果需要使用該功能,還需要安裝用戶態軟件,在CentOS系統中可以使用inotify-tools來實現文件系統的實時監控,該軟件可以從GitHub上(https://github.com/rvoicilas/inotify-tools)或者從SourceForge.net上(https://sourceforge.net/projects/inotify-tools/)下載。
安裝:
注意:以下是在充當Rsync客戶端的192.168.5.5主機上進行操作的
yum install rsync # 安裝rsync
systemctl start rsyncd # 啟動rsync
systemctl enable rsyncd # 允許開機自啟動
yum install -y gcc # 安裝gcc編譯器
# 下載安裝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
監控數據:
inotify-tool提供了兩個應用程序,分別為inotifywait與inotifywatch。其中,inotifywait命令的描述和用法如下。
描述:使用inotify機制等待文件系統事件,該命令非常適合實時監控文件系統的變化。
用法:inotifywait [-hcmrq] [-e <event>] [-t <seconds>] [--format <fmt>] [--timefmt <fmt>] <file>…
選項:
-h,--help | 顯示幫助信息 |
@<file> | 指定監控路徑中的例外文件,應用於不需要監控的文件 |
--fromfile<file> | 從文件中讀取需要監控與例外的文件名稱,每行一個文件名,如果文件名稱以@開頭,則表示例外文件 |
-m,--monitor | 接收到事件后不退出,默認程序在接收一個事件信息后會退出 |
-d,--daemon | 與--monitor類似,但程序會進入后台執行,需要通過--outfile指定事件信息的輸出文件 |
-o,outfile<file> | 將事件信息輸出至文件,默認輸出至標准輸出 |
-s,--syslog | 將錯誤信息輸出至syslog系統日志,默認輸出至標准錯誤輸出 |
-r,--recursive | 遞歸監控 |
-q,--quiet | 靜默模式,不輸出信息 |
--exclude<pattern> | 使用正則表達式匹配例外文件,區分大小寫 |
--excludei<pattern> | 使用正則表達式匹配例外文件,不區分大小寫 |
-t<seconds>,--timeout<seconds> | 在指定的時間沒有發生事件,則退出程序 |
-e<event>,--event<event> | 僅監控指定的事件 |
-c,--csv | 使用CSV格式輸出 |
--timefmt<fmt> | 設置時間格式,即--format指定的%T格式 |
--format<fmt> | 指定輸出信息格式,具體格式參考man手冊 |
實例:創建測試目錄/test和測試用文件/etc/foo,運行inotifywait命令監控/test目錄,然后開啟一個新的終端窗口運行命令cat /test/foo,驗證當發生查看文件事件時,是否會有事件通知。
mkdir -p /test; echo "hello" > /test/foo
/usr/local/inotify/bin/inotifywait /test/
開啟一個新的終端窗口運行命令cat /test/foo,如下圖:
收到事件通知,如下圖:
Rsync與Inotify 雙劍合璧
單一的Rsync工具僅可以進行數據同步,單一的Inotify僅可以實現實時文件監控,而兩者的結合將能滿足企業對數據中心實時數據同步的要求。接下來用案例說明兩者結合部署的流程。在這個案例中,ABC公司需要部署一套Web服務,然而隨着用戶訪問量的增加,單台服務器已經滿足不了大量的並發訪問。因此,ABC公司決定使用集群技術,整合多台服務器處理能力實現負載均衡,從而滿足不斷增加的並發訪問量。
由於Web服務器所提供的網站數據需要保持一致,但當服務器越來越多時,公司發現在這些主機之間同步那些隨時可能發生改變的網站數據簡直就是一場噩夢。我們的解決方案是在后端建立一個數據發布服務器,該服務器作為Rsync客戶端,通過Inotify機制實時監控網站數據,當數據發生變化后調用Rsync命令上傳數據至多個Rsync服務器,這里的Rsync服務器就是提供Web服務的Web服務器。
首先需要在多台Web服務器上部署Rsync服務器,這些Rsync服務器要能夠提供客戶端上傳功能,以實現客戶端主機將數據推送至Rsync服務器,實現數據的實時同步功能。最終我們只要在充當Rsync客戶端的192.168.5.5主機上修改數據,就可以實時推送數據至多台Web服務器。
在數據發布服務器(192.168.5.5)上安裝好下載的 inotify-tool 軟件包,並編寫監控腳本,當監控到數據發生改變時,自動進行數據同步操作,將數據推送至Web服務器(192.168.5.12),這里的腳本名稱為inotify_rsync.sh。
vim inotify_rsync.sh
#!/bin/bash #This Rsync script based on inotify. SRC=/demo/ DEST1=common # DEST2=common2 Client1=192.168.5.12 # Client2=192.168.5.22 User=zhangsan inotify_home=/usr/local/inotify/ #inotify的安裝目錄 Passfile=/etc/rsyncd.secrets [ ! -e $Passfile ] && exit 2 # 判斷Passfile文件是否存在 # Wait for change ${inotify_home}/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f %e' -e close_write,modify,delete,create,move,attrib $SRC | while read line do
echo "$line" >> /var/log/inotify_web 2>&1 # # 對/demo/目錄的操作事件寫入/var/log/inotify_web文件 rsync -avz --delete --progress --password-file=${Passfile} ${SRC} ${User}@${Client1}::${DEST1} # rsync -avz --delete --progress --password-file=/etc/rsyncd.secrets ${SRC} ${User}@${Client2}::${DEST2} done
chmod a+x inotify_rsync.sh # 賦予腳本執行權限
echo "123" > /etc/rsyncd.secrets # 123為虛擬用戶zhangsan的密碼
chmod 600 /etc/rsyncd.secrets # 為密碼提取,增加安全性
調試腳本:
bash -n inotify_rsync.sh
bash -x inotify_rsync.sh
-n:可用於測試shell腳本是否存在語法錯誤,但不會實際執行命令。
-x:進入跟蹤方式,顯示所執行的每一條命令。
遇到如下錯誤:
解決方法:在Rsync服務端(192.168.5.12)配置文件/etc/rsyncd.conf里設置read only=false
再重新執行腳本即可。
本文參考自:
(1)丁明一 編著 《Linux運維之道》
(2)博客:https://blog.51cto.com/lwm666/1981947