1 說在前面的話
rsync官方網站: https://www.samba.org/ftp/rsync/rsync.html
rsync是可以實現增量備份的工具。配合任務計划,rsync能實現定時或間隔同步,配合inotify或sersync,可以實現觸發式的實時同步。
rsync可以實現scp的遠程拷貝(rsync不支持遠程到遠程的拷貝,但scp支持)、cp的本地拷貝、rm刪除和"ls -l"顯示文件列表等功能。但需要注意的是,rsync的最終目的或者說其原始目的是實現兩端主機的文件同步,因此實現的scp/cp/rm等功能僅僅只是同步的輔助手段,且rsync實現這些功能的方式和這些命令是不一樣的。事實上,rsync有一套自己的算法,其算法原理以及rsync對算法實現的機制可能比想象中要復雜一些。平時使用rsync實現簡單的備份、同步等功能足以,沒有多大必要去深究這些原理性的內容。但是想要看懂rsync命令的man文檔、使用"-vvvv"分析rsync執行過程,以及實現rsync更強大更完整的功能,沒有這些理論知識的支持是絕對不可能實現的。本篇文章將簡單介紹rsync的使用方法和它常用的功能。在本篇文章之后的下幾篇文章中,將介紹inotify+rsync和sersync,再之后將詳細解釋rsync相關的原理,其中包括官方技術報告的翻譯(即算法原理)、rsync同步的整個過程(也是官方推薦文章的翻譯),然后專門使用一篇文章通過示例來詳細解釋rsync算法原理,最后給出rsync的man文檔翻譯。希望各位朋友能藉此深入rsync。
2 rsync同步基本說明
rsync的目的是實現本地主機和遠程主機上的文件同步(包括本地推到遠程,遠程拉到本地兩種同步方式),也可以實現本地不同路徑下文件的同步,但不能實現遠程路徑1到遠程路徑2之間的同步(scp可以實現)。
不考慮rsync的實現細節,就文件同步而言,涉及了源文件和目標文件的概念,還涉及了以哪邊文件為同步基准。例如,想讓目標主機上的文件和本地文件保持同步,則是以本地文件為同步基准,將本地文件作為源文件推送到目標主機上。反之,如果想讓本地主機上的文件和目標主機上的文件保持同步,則目標主機上的文件為同步基准,實現方式是將目標主機上的文件作為源文件拉取到本地。當然,要保持本地的兩個文件相互同步,rsync也一樣能實現,這就像Linux中cp命令一樣,以本地某文件作為源,另一文件作為目標文件,但請注意,雖然rsync和cp能達到相同的目的,但它們的實現方式是不一樣的。
既然是文件同步,在同步過程中必然會涉及到源和目標兩文件之間版本控制的問題,例如是否要刪除源主機上沒有但目標上多出來的文件,目標文件比源文件更新(newer than source)時是否仍要保持同步,遇到軟鏈接時是拷貝軟鏈接本身還是拷貝軟鏈接所指向的文件,目標文件已存在時是否要先對其做個備份等等。
rsync同步過程中由兩部分模式組成:決定哪些文件需要同步的檢查模式以及文件同步時的同步模式。
(1).檢查模式是指按照指定規則來檢查哪些文件需要被同步,例如哪些文件是明確被排除不傳輸的。默認情況下,rsync使用"quick check"算法快速檢查源文件和目標文件的大小、mtime(修改時間)是否一致,如果不一致則需要傳輸。當然,也可以通過在rsync命令行中指定某些選項來改變quick check的檢查模式,比如"--size-only"選項表示"quick check"將僅檢查文件大小不同的文件作為待傳輸文件。rsync支持非常多的選項,其中檢查模式的自定義性是非常有彈性的。
(2).同步模式是指在文件確定要被同步后,在同步過程發生之前要做哪些額外工作。例如上文所說的是否要先刪除源主機上沒有但目標主機上有的文件,是否要先備份已存在的目標文件,是否要追蹤鏈接文件等額外操作。rsync也提供非常多的選項使得同步模式變得更具彈性。
相對來說,為rsync手動指定同步模式的選項更常見一些,只有在有特殊需求時才指定檢查模式,因為大多數檢查模式選項都可能會影響rsync的性能。
3.選項說明和示例
接下來是rsync的選項說明。
-v:顯示rsync過程中詳細信息。可以使用"-vvvv"獲取更詳細信息。 -P:顯示文件傳輸的進度信息。(實際上"-P"="--partial --progress",其中的"--progress"才是顯示進度信息的)。 -n --dry-run :僅測試傳輸,而不實際傳輸。常和"-vvvv"配合使用來查看rsync是如何工作的。 -a --archive :歸檔模式,表示遞歸傳輸並保持文件屬性。等同於"-rtopgDl"。 -r --recursive:遞歸到目錄中去。 -t --times:保持mtime屬性。強烈建議任何時候都加上"-t",否則目標文件mtime會設置為系統時間,導致下次更新 :檢查出mtime不同從而導致增量傳輸無效。 -o --owner:保持owner屬性(屬主)。 -g --group:保持group屬性(屬組)。 -p --perms:保持perms屬性(權限,不包括特殊權限)。 -D :是"--device --specials"選項的組合,即也拷貝設備文件和特殊文件。 -l --links:如果文件是軟鏈接文件,則拷貝軟鏈接本身而非軟鏈接所指向的對象。 -z :傳輸時進行壓縮提高效率。 -R --relative:使用相對路徑。意味着將命令行中指定的全路徑而非路徑最尾部的文件名發送給服務端,包括它們的屬性。用法見下文示例。 --size-only :默認算法是檢查文件大小和mtime不同的文件,使用此選項將只檢查文件大小。 -u --update :僅在源mtime比目標已存在文件的mtime新時才拷貝。注意,該選項是接收端判斷的,不會影響刪除行為。 -d --dirs :以不遞歸的方式拷貝目錄本身。默認遞歸時,如果源為"dir1/file1",則不會拷貝dir1目錄,使用該選項將拷貝dir1但不拷貝file1。 --max-size :限制rsync傳輸的最大文件大小。可以使用單位后綴,還可以是一個小數值(例如:"--max-size=1.5m") --min-size :限制rsync傳輸的最小文件大小。這可以用於禁止傳輸小文件或那些垃圾文件。 --exclude :指定排除規則來排除不需要傳輸的文件。 --delete :以SRC為主,對DEST進行同步。多則刪之,少則補之。注意"--delete"是在接收端執行的,所以它是在 :exclude/include規則生效之后才執行的。 -b --backup :對目標上已存在的文件做一個備份,備份的文件名后默認使用"~"做后綴。 --backup-dir:指定備份文件的保存路徑。不指定時默認和待備份文件保存在同一目錄下。 -e :指定所要使用的遠程shell程序,默認為ssh。 --port :連接daemon時使用的端口號,默認為873端口。 --password-file:daemon模式時的密碼文件,可以從中讀取密碼實現非交互式。注意,這不是遠程shell認證的密碼,而是rsync模塊認證的密碼。 -W --whole-file:rsync將不再使用增量傳輸,而是全量傳輸。在網絡帶寬高於磁盤帶寬時,該選項比增量傳輸更高效。 --existing :要求只更新目標端已存在的文件,目標端還不存在的文件不傳輸。注意,使用相對路徑時如果上層目錄不存在也不會傳輸。 --ignore-existing:要求只更新目標端不存在的文件。和"--existing"結合使用有特殊功能,見下文示例。 --remove-source-files:要求刪除源端已經成功傳輸的文件。
--list-only:該選項強制rsync僅列出源路徑的文件列表而不是進行文件傳輸。如果rsync命令行中只給出了一個地址,將隱含該選項。注意通配符會被shell解析並擴展為rsync的參數
4.daemon配置文件rsyncd.conf
默認"rsync --daemon"讀取的配置文件為/etc/rsyncd.conf,有些版本的系統上可能該文件默認不存在。rsyncd.conf的配置見man rsyncd.conf。以下是部分內容:
[root@xuexi ~]# cat /etc/rsyncd.conf # /etc/rsyncd: configuration file for rsync daemon mode # See rsyncd.conf man page for more options. # configuration example: # uid = nobody # gid = nobody # use chroot = yes # max connections = 4 # pid file = /var/run/rsyncd.pid # exclude = lost+found/ # transfer logging = yes # timeout = 900 # ignore nonreadable = yes # dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 # [ftp1] # path = /home/ftp # comment = ftp export area
在上述示例配置文件中,先定義了一些全局選項,然后定義了[ftp1],這個用中括號包圍的"[ftp1]"就是rsync中所謂的模塊,ftp1為模塊ID,必須保證唯一,每個模塊中必須定義一項"path",path定義的是該模塊代表的路徑,例如此示例文件中,如果想請求ftp1模塊,則在客戶端使用"rsync user@host::ftp1",這表示訪問user@host上的/home/ftp目錄,如果要訪問/home/ftp目錄下的子目錄www,則"rsync user@host::ftp1/www"。
以下是常見的配置項,也算是一個配置示例:
######### 全局配置參數 ########## port=888 # 指定rsync端口。默認873 uid = rsync # rsync服務的運行用戶,默認是nobody,文件傳輸成功后屬主將是這個uid gid = rsync # rsync服務的運行組,默認是nobody,文件傳輸成功后屬組將是這個gid use chroot = no # rsync daemon在傳輸前是否切換到指定的path目錄下,並將其監禁在內 max connections = 200 # 指定最大連接數量,0表示沒有限制 timeout = 300 # 確保rsync服務器不會永遠等待一個崩潰的客戶端,0表示永遠等待 motd file = /var/rsyncd/rsync.motd # 客戶端連接過來顯示的消息 pid file = /var/run/rsyncd.pid # 指定rsync daemon的pid文件 lock file = /var/run/rsync.lock # 指定鎖文件 log file = /var/log/rsyncd.log # 指定rsync的日志文件,而不把日志發送給syslog dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 # 指定哪些文件不用進行壓縮傳輸 ###########下面指定模塊,並設定模塊配置參數,可以創建多個模塊########### [longshuai] # 模塊ID path = /longshuai/ # 指定該模塊的路徑,該參數必須指定。啟動rsync服務前該目錄必須存在。rsync請求訪問模塊本質就是訪問該路徑。 ignore errors # 忽略某些IO錯誤信息 read only = false # 指定該模塊是否可讀寫,即能否上傳文件,false表示可讀寫,true表示可讀不可寫。所有模塊默認不可上傳 write only = false # 指定該模式是否支持下載,設置為true表示客戶端不能下載。所有模塊默認可下載 list = false # 客戶端請求顯示模塊列表時,該模塊是否顯示出來,設置為false則該模塊為隱藏模塊。默認true hosts allow = 10.0.0.0/24 # 指定允許連接到該模塊的機器,多個ip用空格隔開或者設置區間 hosts deny = 0.0.0.0/32 # 指定不允許連接到該模塊的機器 auth users = rsync_backup # 指定連接到該模塊的用戶列表,只有列表里的用戶才能連接到模塊,用戶名和對應密碼保存在secrts file中, # 這里使用的不是系統用戶,而是虛擬用戶。不設置時,默認所有用戶都能連接,但使用的是匿名連接 secrets file = /etc/rsyncd.passwd # 保存auth users用戶列表的用戶名和密碼,每行包含一個username:passwd。由於"strict modes" # 默認為true,所以此文件要求非rsync daemon用戶不可讀寫。只有啟用了auth users該選項才有效。 [xiaofang] # 以下定義的是第二個模塊 path=/xiaofang/ read only = false ignore errors comment = anyone can access
注意:
(1).客戶端推到服務端時,文件的屬主和屬組是配置文件中指定的uid和gid。但是客戶端從服務端拉的時候,文件的屬主和屬組是客戶端正在操作rsync的用戶身份,因為執行rsync程序的用戶為當前用戶。
(2).auth users和secrets file這兩行不是一定需要的,省略它們時將默認使用匿名連接。但是如果使用了它們,則secrets file的權限必須是600。客戶端的密碼文件也必須是600。
(3).關於secrets file的權限,實際上並非一定是600,只要滿足除了運行rsync daemon的用戶可讀即可。是否檢查權限的設定是通過選項strict mode設置的,如果設置為false,則無需關注文件的權限。但默認是yes,即需要設置權限。
5.配置實例:
一、服務器不開啟daemon進程,客戶端如何同步信息
1.服務端添加一個匿名模塊
[anonymity] path=/var/anonymity comment=anonymuty_write read only=no ignore errors
2.rsync --list-only -e "ssh -l root" 192.168.9.7::anonymity /var/anonymity/ # 客戶端使用ssh建立連接,如果后邊沒有跟本地目錄,則會將目標服務器的文件顯示在屏幕
二、服務器開啟daemon進程,客戶端同步信息
1.配置模塊
[xuan] path=/var/rsync # 設置路徑 comment=rsync_xuan # 解釋信息 read only=yes # 只讀 auth users = xuan # 認證的用戶名 secrets file = /etc/rsync.passwd # 存放密碼的文件
2.創建模塊中secrets file指定的密碼文件
vim /etc/rsync.passwd
xuan:pwd123 # pwd123是密碼
3./etc/rsync.passwd的權限設置為600,這步必須有
chmod 600 /etc/rsync.passwd
4.客戶端進行連接
rsync --port 9205 xuan@192.168.9.7::xuan
6.inotify+rsync
1.安裝inotify-tools
inotify由inotify-tools包提供。在安裝inotify-tools之前,請確保內核版本高於2.6.13,且在/proc/sys/fs/inotify目錄下有以下三項,這表示系統支持inotify監控,關於這3項的意義,下文會簡單解釋。
[root@node1 tmp]# ll /proc/sys/fs/inotify/ total 0 -rw-r--r-- 1 root root 0 Feb 11 19:57 max_queued_events -rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_instances -rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_watches
epel源上提供了inotify-tools工具,或者下載源碼包格式進行編譯。
inotify-tools源碼包地址:http://www.p-pp.cn/app/rsync/inotify-tools-3.14.tar.gz
[root@localhost inotify-tools-3.14]# inotifywait -mrq -e modify,create,move,delete /var/www/html/
-m:持續監控
-r:遞歸整個目錄
-q:簡化輸出信息
2.inotify+rsync示例腳本
#!/bin/bash
INOTIFY_CMD="inotifywait -mrq -e modify,create,move,delete /var/www/html"
RSYNC_CMD="rsync -avzH --delete --password-file=/etc/server.pass /var/www/html/ backuper@192.168.4.200::wwwroot"
$INOTIFY_CMD | while read DIRECTORY EVENT FILE
do
$RSYNC_CMD
done