rsync算法原理及使用
如果服務(wù)器之間需要保持某些文件的一致,我們可以使用scp來(lái)復(fù)制,如果需要長(zhǎng)期保持一致,可以配合crontab腳本來(lái)使用。但是此時(shí)我們有更優(yōu)的方式,就是rsync+crontab來(lái)實(shí)現(xiàn)定時(shí)增量傳輸保持文件一致。
rsync功能很強(qiáng)大,網(wǎng)上的資料也都很全,這里做一些簡(jiǎn)單的匯總。
rsync原理
這一小節(jié)內(nèi)容大幅度轉(zhuǎn)載了?RSYNC 的核心算法?的內(nèi)容,因?yàn)樵恼聦?xiě)的太好,就不再狗尾續(xù)貂了,感興趣的可以直接查看原文。他的翻譯原文是:The rsync algorithm。rsync是linux下同步文件的一個(gè)高效算法,用于同步更新兩處計(jì)算機(jī)的文件和目錄,并適當(dāng)利用查找文件中的不同塊以減少數(shù)據(jù)傳輸。rsync的主要特點(diǎn)就是增量傳輸,只對(duì)變更的部分進(jìn)行傳送。
增量同步算法
假如我們現(xiàn)在需要同步兩個(gè)文件保持一致,并且只想傳送不同的部分,那么我們就需要對(duì)兩邊的文件做diff,但是這兩個(gè)問(wèn)題在兩臺(tái)不同的機(jī)器上,無(wú)法做diff。如果我們做diff,就要把一個(gè)文件傳到另一臺(tái)機(jī)器上做diff,但這樣一來(lái),我們就傳了整個(gè)文件,這與我們只想傳輸不同部的初衷相背。于是我們就要想一個(gè)辦法,讓這兩邊的文件見(jiàn)不到面,但還能知道它們間有什么不同。這就是rsync的算法。
rsync同步算法
我們將同步源文件名稱(chēng)為fileSrc,同步目的文件叫fileDst。
1. 分塊Checksum算法
首先,我們會(huì)把fileDst的文件平均切分成若干個(gè)小塊,比如每塊512個(gè)字節(jié)(最后一塊會(huì)小于這個(gè)數(shù)),然后對(duì)每塊計(jì)算兩個(gè)checksum:
為什么要這樣?因?yàn)槿舾赡昵暗挠布吓躮d4的算法太慢了,所以,我們需要一個(gè)快算法來(lái)鑒別文件塊的不同,但是弱的adler32算法碰撞概率太高了,所以我們還要引入強(qiáng)的checksum算法以保證兩文件塊是相同的。也就是說(shuō),弱的checksum是用來(lái)區(qū)別不同,而強(qiáng)的是用來(lái)確認(rèn)相同。
2. 傳輸算法
同步目標(biāo)端會(huì)把fileDst的一個(gè)checksum列表傳給同步源,這個(gè)列表里包括了三個(gè)東西,rolling checksum(32bits),md5 checksume(128bits),文件塊編號(hào)。
同步源機(jī)器拿到了這個(gè)列表后,會(huì)對(duì)fileSrc做同樣的checksum,然后和fileDst的checksum做對(duì)比,這樣就知道哪些文件塊改變了。
但是,聰明的你一定會(huì)有以下兩個(gè)疑問(wèn):
如果我fileSrc這邊在文件中間加了一個(gè)字符,這樣后面的文件塊都會(huì)位移一個(gè)字符,這樣就完全和fileDst這邊的不一樣了,但理論上來(lái)說(shuō),我應(yīng)該只需要傳一個(gè)字符就好了。這個(gè)怎么解決? 如果這個(gè)checksum列表特別長(zhǎng),而我的兩邊的相同的文件塊可能并不是一樣的順序,那就需要查找,線性的查找起來(lái)應(yīng)該特別慢吧。這個(gè)怎么解決? 很好,讓我們來(lái)看一下同步源端的算法。
3.?checksum查找算法
同步源端拿到fileDst的checksum數(shù)組后,會(huì)把這個(gè)數(shù)據(jù)存到一個(gè)hash table(特殊的數(shù)據(jù)結(jié)構(gòu)體,可以快速檢索)中,用rolling checksum做hash,以便獲得O(1)時(shí)間復(fù)雜度的查找性能。這個(gè)hash table是16bits的,所以,hash table的尺寸是2的16次方,對(duì)rolling checksum的hash會(huì)被散列到0 到 2^16 – 1中的某個(gè)整數(shù)值。
4. 比對(duì)算法
1. 取fileSrc的第一個(gè)文件塊(我們假設(shè)的是512個(gè)長(zhǎng)度),也就是從fileSrc的第1個(gè)字節(jié)到第512個(gè)字節(jié),取出來(lái)后做rolling checksum計(jì)算。計(jì)算好的值到hash表中查。
5. 傳輸
最終在同步源這端,我們的rsync算法可能會(huì)得到這個(gè)樣子的一個(gè)數(shù)據(jù)數(shù)組,圖中,紅色塊表示在目標(biāo)端已匹配上,不用傳輸(注:我專(zhuān)門(mén)在其中顯示了兩塊chunk #5,代表數(shù)據(jù)中有復(fù)制的地方,不用傳輸),而白色的地方就是需要傳輸?shù)膬?nèi)容(注意:這些白色的塊是不定長(zhǎng)的),這樣,同步源這端把這個(gè)數(shù)組(白色的就是實(shí)際內(nèi)容,紅色的就放一個(gè)標(biāo)號(hào))壓縮傳到目的端,在目的端的rsync會(huì)根據(jù)這個(gè)表重新生成文件,這樣,同步完成。
最后想說(shuō)一下,對(duì)于某些壓縮文件使用rsync傳輸可能會(huì)傳得更多,因?yàn)楸粔嚎s后的文件可能會(huì)非常的不同。對(duì)此,對(duì)于gzip和bzip2這樣的命令,記得開(kāi)啟?“rsyncalbe”?模式。
rsync的使用
同樣的,這一小節(jié)內(nèi)容也是大幅度轉(zhuǎn)載了?第2章 rsync(一):基本命令和用法?的內(nèi)容,因?yàn)樵恼潞苋?#xff0c;感興趣的可以直接查看原文。rsync是實(shí)現(xiàn)增量備份的工具。配合任務(wù)計(jì)劃,rsync能實(shí)現(xiàn)定時(shí)或間隔同步,配合inotify或sersync,可以實(shí)現(xiàn)觸發(fā)式的實(shí)時(shí)同步。它的目的是實(shí)現(xiàn)本地主機(jī)和遠(yuǎn)程主機(jī)上的文件同步(包括本地推到遠(yuǎn)程,遠(yuǎn)程拉到本地兩種同步方式),也可以實(shí)現(xiàn)本地不同路徑下文件的同步,但不能實(shí)現(xiàn)遠(yuǎn)程路徑1到遠(yuǎn)程路徑2之間的同步(scp可以實(shí)現(xiàn))。
rsync同步過(guò)程中由兩部分組成:決定哪些文件需要同步的檢查模式以及文件同步時(shí)的同步模式。
相對(duì)來(lái)說(shuō),為rsync手動(dòng)指定同步模式的選項(xiàng)更常見(jiàn)一些,只有在有特殊需求時(shí)才指定檢查模式,因?yàn)榇蠖鄶?shù)檢查模式選項(xiàng)都可能會(huì)影響rsync的性能。
rsync四種工作方式
rsync的基礎(chǔ)語(yǔ)法為:rsync [OPTION...] SRC... [DEST]
支持的參數(shù)高達(dá)一百多個(gè),最常用的選項(xiàng)組合是"avz",即壓縮和顯示部分信息,并以歸檔模式傳輸。詳細(xì)的可以參考?博客園-man rsync翻譯(rsync命令中文手冊(cè)),下面是部分參數(shù)說(shuō)明:
-v:顯示rsync過(guò)程中詳細(xì)信息。可以使用"-vvvv"獲取更詳細(xì)信息。 -P:顯示文件傳輸?shù)倪M(jìn)度信息。(實(shí)際上"-P"="--partial --progress",其中的"--progress"才是顯示進(jìn)度信息的)。 -n --dry-run :僅測(cè)試傳輸,而不實(shí)際傳輸。常和"-vvvv"配合使用來(lái)查看rsync是如何工作的。 -a --archive :歸檔模式,表示遞歸傳輸并保持文件屬性。等同于"-rtopgDl"。 -r --recursive:遞歸到目錄中去。 -t --times:保持mtime屬性。強(qiáng)烈建議任何時(shí)候都加上"-t",否則目標(biāo)文件mtime會(huì)設(shè)置為系統(tǒng)時(shí)間,導(dǎo)致下次更新:檢查出mtime不同從而導(dǎo)致增量傳輸無(wú)效。 -o --owner:保持owner屬性(屬主)。 -g --group:保持group屬性(屬組)。 -p --perms:保持perms屬性(權(quán)限,不包括特殊權(quán)限)。 -D :是"--device --specials"選項(xiàng)的組合,即也拷貝設(shè)備文件和特殊文件。 -l --links:如果文件是軟鏈接文件,則拷貝軟鏈接本身而非軟鏈接所指向的對(duì)象。 -z :傳輸時(shí)進(jìn)行壓縮提高效率。 -R --relative:使用相對(duì)路徑。意味著將命令行中指定的全路徑而非路徑最尾部的文件名發(fā)送給服務(wù)端,包括它們的屬性。用法見(jiàn)下文示例。 --size-only :默認(rèn)算法是檢查文件大小和mtime不同的文件,使用此選項(xiàng)將只檢查文件大小。 -u --update :僅在源mtime比目標(biāo)已存在文件的mtime新時(shí)才拷貝。注意,該選項(xiàng)是接收端判斷的,不會(huì)影響刪除行為。 -d --dirs :以不遞歸的方式拷貝目錄本身。默認(rèn)遞歸時(shí),如果源為"dir1/file1",則不會(huì)拷貝dir1目錄,使用該選項(xiàng)將拷貝dir1但不拷貝file1。 --max-size :限制rsync傳輸?shù)淖畲笪募笮 ?梢允褂脝挝缓缶Y,還可以是一個(gè)小數(shù)值(例如:"--max-size=1.5m") --min-size :限制rsync傳輸?shù)淖钚∥募笮 _@可以用于禁止傳輸小文件或那些垃圾文件。 --exclude :指定排除規(guī)則來(lái)排除不需要傳輸?shù)奈募?--delete :以SRC為主,對(duì)DEST進(jìn)行同步。多則刪之,少則補(bǔ)之。注意"--delete"是在接收端執(zhí)行的,所以它是在:exclude/include規(guī)則生效之后才執(zhí)行的。 -b --backup :對(duì)目標(biāo)上已存在的文件做一個(gè)備份,備份的文件名后默認(rèn)使用"~"做后綴。 --backup-dir:指定備份文件的保存路徑。不指定時(shí)默認(rèn)和待備份文件保存在同一目錄下。 -e :指定所要使用的遠(yuǎn)程shell程序,默認(rèn)為ssh。 --port :連接daemon時(shí)使用的端口號(hào),默認(rèn)為873端口。 --password-file:daemon模式時(shí)的密碼文件,可以從中讀取密碼實(shí)現(xiàn)非交互式。注意,這不是遠(yuǎn)程shell認(rèn)證的密碼,而是rsync模塊認(rèn)證的密碼。 -W --whole-file:rsync將不再使用增量傳輸,而是全量傳輸。在網(wǎng)絡(luò)帶寬高于磁盤(pán)帶寬時(shí),該選項(xiàng)比增量傳輸更高效。 --existing :要求只更新目標(biāo)端已存在的文件,目標(biāo)端還不存在的文件不傳輸。注意,使用相對(duì)路徑時(shí)如果上層目錄不存在也不會(huì)傳輸。 --ignore-existing:要求只更新目標(biāo)端不存在的文件。和"--existing"結(jié)合使用有特殊功能,見(jiàn)下文示例。 --remove-source-files:要求刪除源端已經(jīng)成功傳輸?shù)奈募?1. 本地文件系統(tǒng)上實(shí)現(xiàn)同步
rsync [OPTION...] SRC... [DEST]2. 本地主機(jī)使用遠(yuǎn)程shell和遠(yuǎn)程主機(jī)通信
Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]Push: rsync [OPTION...] SRC... [USER@]HOST:DEST3. 本地主機(jī)通過(guò)網(wǎng)絡(luò)套接字連接遠(yuǎn)程主機(jī)上的rsync daemon
Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]Push: rsync [OPTION...] SRC... [USER@]HOST::DESTrsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST前兩者的本質(zhì)是通過(guò)管道通信,即使是遠(yuǎn)程shell。而方式(3)則是讓遠(yuǎn)程主機(jī)上運(yùn)行rsync服務(wù),使其監(jiān)聽(tīng)在一個(gè)端口上,等待客戶(hù)端的連接。
路徑的格式可以是本地路徑,也可以是使用user@host:path或user@host::path的遠(yuǎn)程路徑,如果主機(jī)和path路徑之間使用單個(gè)冒號(hào)隔開(kāi),表示使用的是遠(yuǎn)程shell通信方式,而使用雙冒號(hào)隔開(kāi)的則表示的是連接rsync daemon。另外,連接rsync daemon時(shí),還提供了URL格式的路徑表述方式rsync://user@host/path。
4. 遠(yuǎn)程shell臨時(shí)啟動(dòng)一個(gè)rsync daemon
rsync [options] --rsh=ssh auth_user@host::module rsync [options] --rsh="ssh -l ssh_user" auth_user@host::module rsync [options] -e "ssh -l ssh_user" auth_user@host::module rsync [options] -e "ssh -l ssh_user" rsync://auth_user@host/module這不同于方式(3),它不要求遠(yuǎn)程主機(jī)上事先啟動(dòng)rsync服務(wù),而是臨時(shí)派生出rsync daemon,它是單用途的一次性daemon,僅用于臨時(shí)讀取daemon的配置文件,當(dāng)此次rsync同步完成,遠(yuǎn)程shell啟動(dòng)的rsync daemon進(jìn)程也會(huì)自動(dòng)消逝。此通信方式的命令行語(yǔ)法格式同"Access via rsync daemon",但要求options部分必須明確指定"--rsh"選項(xiàng)或其短選項(xiàng)"-e"。
一些用法示例
# 將/etc/fstab拷貝到/tmp目錄下 rsync /etc/fstab /tmp # 將/etc/cron.d目錄拷貝到/tmp下 rsync -r /etc/cron.d /tmp # 將/etc/cron.d目錄拷貝到/tmp下,但要求在/tmp下也生成etc子目 rsync -R -r /etc/cron.d /tmp # 拷貝源路徑較長(zhǎng),但只保留一部分目錄結(jié)構(gòu),使用一個(gè)點(diǎn)代表相對(duì)路徑的起始位置 rsync -R -r /var/./log/anaconda /tmp # 對(duì)遠(yuǎn)程目錄下已存在文件做備份,備份后綴為"~",使用"--suffix"指定后綴 rsync -R -r --backup /var/./log/anaconda /tmp # 指定備份文件保存路徑,默認(rèn)將不會(huì)加備份后綴,使用"--suffix"顯式指定后綴 rsync -R -r --backup --backup-dir=/tmp/log_back /var/./log/anaconda /tmp # .指定ssh連接參數(shù),如端口、連接的用戶(hù)、ssh選項(xiàng)等 rsync -e "ssh -p 22 -o StrictHostKeyChecking=no" /etc/fstab 172.16.10.5:/tmp # 使用"--existing"選項(xiàng)使得只更新目標(biāo)端已存在的文件 rsync -r -v --existing /tmp/a/ /tmp/b # "--ignore-existing"更新目標(biāo)端不存在的文件 rsync -r -v --ignore-existing /tmp/a/ /tmp/b # "--remove-source-files"刪除源端文件 rsync -r -v --remove-source-files /tmp/a/anaconda /tmp/a/audit /tmp # 使用"--exclude"選項(xiàng)指定排除規(guī)則,排除那些不需要傳輸?shù)奈募?rsync -r -v --exclude="anaconda/*.log" /var/log/anaconda /var/log/audit /tmp如果僅有一個(gè)SRC或DEST參數(shù),則將以類(lèi)似于"ls -l"的方式列出源文件列表(只有一個(gè)路徑參數(shù),總會(huì)認(rèn)為是源文件),而不是復(fù)制文件。
源路徑如果是一個(gè)目錄的話,帶上尾隨斜線和不帶尾隨斜線是不一樣的,不帶尾隨斜線表示的是整個(gè)目錄包括目錄本身,帶上尾隨斜線表示的是目錄中的文件,不包括目錄本身。
# 在/tmp目錄下創(chuàng)建etc目錄 [root@xuexi ~]# rsync -a /etc /tmp # 不會(huì)在/tmp目錄下創(chuàng)建etc目錄,源路徑/etc/中的所有文件都直接放在/tmp目錄下 [root@xuexi ~]# rsync -a /etc/ /tmp參考資料
總結(jié)
以上是生活随笔為你收集整理的rsync算法原理及使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大七座奶爸神车!五菱佳辰上市:6.88万
- 下一篇: 第十一节:特性(常见的特性标签、自定义特