日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

rsync算法原理及使用

發(fā)布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rsync算法原理及使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

如果服務(wù)器之間需要保持某些文件的一致,我們可以使用scp來復(fù)制,如果需要長期保持一致,可以配合crontab腳本來使用。但是此時我們有更優(yōu)的方式,就是rsync+crontab來實(shí)現(xiàn)定時增量傳輸保持文件一致。

rsync功能很強(qiáng)大,網(wǎng)上的資料也都很全,這里做一些簡單的匯總。

rsync原理

這一小節(jié)內(nèi)容大幅度轉(zhuǎn)載了?RSYNC 的核心算法?的內(nèi)容,因?yàn)樵恼聦懙奶?#xff0c;就不再狗尾續(xù)貂了,感興趣的可以直接查看原文。他的翻譯原文是:The rsync algorithm。

rsync是linux下同步文件的一個高效算法,用于同步更新兩處計(jì)算機(jī)的文件和目錄,并適當(dāng)利用查找文件中的不同塊以減少數(shù)據(jù)傳輸。rsync的主要特點(diǎn)就是增量傳輸,只對變更的部分進(jìn)行傳送。

增量同步算法

假如我們現(xiàn)在需要同步兩個文件保持一致,并且只想傳送不同的部分,那么我們就需要對兩邊的文件做diff,但是這兩個問題在兩臺不同的機(jī)器上,無法做diff。如果我們做diff,就要把一個文件傳到另一臺機(jī)器上做diff,但這樣一來,我們就傳了整個文件,這與我們只想傳輸不同部的初衷相背。于是我們就要想一個辦法,讓這兩邊的文件見不到面,但還能知道它們間有什么不同。這就是rsync的算法。

rsync同步算法

我們將同步源文件名稱為fileSrc,同步目的文件叫fileDst。

1. 分塊Checksum算法

首先,我們會把fileDst的文件平均切分成若干個小塊,比如每塊512個字節(jié)(最后一塊會小于這個數(shù)),然后對每塊計(jì)算兩個checksum:

  • 一個叫rolling checksum,是弱checksum,32位的checksum
  • 另一個是強(qiáng)checksum,128位的,以前用md4,現(xiàn)在用md5 hash算法。
  • 為什么要這樣?因?yàn)槿舾赡昵暗挠布吓躮d4的算法太慢了,所以,我們需要一個快算法來鑒別文件塊的不同,但是弱的adler32算法碰撞概率太高了,所以我們還要引入強(qiáng)的checksum算法以保證兩文件塊是相同的。也就是說,弱的checksum是用來區(qū)別不同,而強(qiáng)的是用來確認(rèn)相同。

    2. 傳輸算法

    同步目標(biāo)端會把fileDst的一個checksum列表傳給同步源,這個列表里包括了三個東西,rolling checksum(32bits),md5 checksume(128bits),文件塊編號。

    同步源機(jī)器拿到了這個列表后,會對fileSrc做同樣的checksum,然后和fileDst的checksum做對比,這樣就知道哪些文件塊改變了。

    但是,聰明的你一定會有以下兩個疑問:

    如果我fileSrc這邊在文件中間加了一個字符,這樣后面的文件塊都會位移一個字符,這樣就完全和fileDst這邊的不一樣了,但理論上來說,我應(yīng)該只需要傳一個字符就好了。這個怎么解決? 如果這個checksum列表特別長,而我的兩邊的相同的文件塊可能并不是一樣的順序,那就需要查找,線性的查找起來應(yīng)該特別慢吧。這個怎么解決? 很好,讓我們來看一下同步源端的算法。

    3.?checksum查找算法

    同步源端拿到fileDst的checksum數(shù)組后,會把這個數(shù)據(jù)存到一個hash table(特殊的數(shù)據(jù)結(jié)構(gòu)體,可以快速檢索)中,用rolling checksum做hash,以便獲得O(1)時間復(fù)雜度的查找性能。這個hash table是16bits的,所以,hash table的尺寸是2的16次方,對rolling checksum的hash會被散列到0 到 2^16 – 1中的某個整數(shù)值。

    4. 比對算法

    1. 取fileSrc的第一個文件塊(我們假設(shè)的是512個長度),也就是從fileSrc的第1個字節(jié)到第512個字節(jié),取出來后做rolling checksum計(jì)算。計(jì)算好的值到hash表中查。

  • 如果查到了,說明發(fā)現(xiàn)在fileDst中有潛在相同的文件塊,于是就再比較md5的checksum,因?yàn)閞olling checksume太弱了,可能發(fā)生碰撞。于是還要算md5的128bits的checksum,這樣一來,我們就有2^-(32+128) = 2^-160的概率發(fā)生碰撞,這太小了可以忽略。如果rolling checksum和md5 checksum都相同,這說明在fileDst中有相同的塊,我們需要記下這一塊在fileDst下的文件編號。
  • 如果fileSrc的rolling checksum?沒有在hash table中找到,那就不用算md5 checksum了。表示這一塊中有不同的信息。總之,只要rolling checksum?或?md5 checksum?其中有一個在fileDst的checksum hash表中找不到匹配項(xiàng),那么就會觸發(fā)算法對fileSrc的rolling動作。于是,算法會住后step 1個字節(jié),取fileSrc中字節(jié)2-513的文件塊要做checksum,go to (1.)– 現(xiàn)在你明白什么叫rolling checksum了吧。
  • 這樣,我們就可以找出fileSrc相鄰兩次匹配中的那些文本字符,這些就是我們要往同步目標(biāo)端傳的文件內(nèi)容了。
  • 5. 傳輸

    最終在同步源這端,我們的rsync算法可能會得到這個樣子的一個數(shù)據(jù)數(shù)組,圖中,紅色塊表示在目標(biāo)端已匹配上,不用傳輸(注:我專門在其中顯示了兩塊chunk #5,代表數(shù)據(jù)中有復(fù)制的地方,不用傳輸),而白色的地方就是需要傳輸?shù)膬?nèi)容(注意:這些白色的塊是不定長的),這樣,同步源這端把這個數(shù)組(白色的就是實(shí)際內(nèi)容,紅色的就放一個標(biāo)號)壓縮傳到目的端,在目的端的rsync會根據(jù)這個表重新生成文件,這樣,同步完成。

    最后想說一下,對于某些壓縮文件使用rsync傳輸可能會傳得更多,因?yàn)楸粔嚎s后的文件可能會非常的不同。對此,對于gzip和bzip2這樣的命令,記得開啟?“rsyncalbe”?模式。

    rsync的使用

    同樣的,這一小節(jié)內(nèi)容也是大幅度轉(zhuǎn)載了?第2章 rsync(一):基本命令和用法?的內(nèi)容,因?yàn)樵恼潞苋?#xff0c;感興趣的可以直接查看原文。

    rsync是實(shí)現(xiàn)增量備份的工具。配合任務(wù)計(jì)劃,rsync能實(shí)現(xiàn)定時或間隔同步,配合inotify或sersync,可以實(shí)現(xiàn)觸發(fā)式的實(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ù)摹DJ(rèn)情況下,rsync使用"quick check"算法快速檢查源文件和目標(biāo)文件的大小、mtime(修改時間)是否一致,如果不一致則需要傳輸。當(dāng)然,也可以通過在rsync命令行中指定某些選項(xiàng)來改變quick check的檢查模式,比如"--size-only"選項(xiàng)表示"quick check"將僅檢查文件大小不同的文件作為待傳輸文件。rsync支持非常多的選項(xiàng),其中檢查模式的自定義性是非常有彈性的。
  • 同步模式是指在文件確定要被同步后,在同步過程發(fā)生之前要做哪些額外工作。例如上文所說的是否要先刪除源主機(jī)上沒有但目標(biāo)主機(jī)上有的文件,是否要先備份已存在的目標(biāo)文件,是否要追蹤鏈接文件等額外操作。rsync也提供非常多的選項(xiàng)使得同步模式變得更具彈性。
  • 相對來說,為rsync手動指定同步模式的選項(xiàng)更常見一些,只有在有特殊需求時才指定檢查模式,因?yàn)榇蠖鄶?shù)檢查模式選項(xiàng)都可能會影響rsync的性能。

    rsync四種工作方式

    rsync的基礎(chǔ)語法為:rsync [OPTION...] SRC... [DEST]

    支持的參數(shù)高達(dá)一百多個,最常用的選項(xiàng)組合是"avz",即壓縮和顯示部分信息,并以歸檔模式傳輸。詳細(xì)的可以參考?博客園-man rsync翻譯(rsync命令中文手冊),下面是部分參數(shù)說明:

    -v:顯示rsync過程中詳細(xì)信息。可以使用"-vvvv"獲取更詳細(xì)信息。 -P:顯示文件傳輸?shù)倪M(jìn)度信息。(實(shí)際上"-P"="--partial --progress",其中的"--progress"才是顯示進(jìn)度信息的)。 -n --dry-run :僅測試傳輸,而不實(shí)際傳輸。常和"-vvvv"配合使用來查看rsync是如何工作的。 -a --archive :歸檔模式,表示遞歸傳輸并保持文件屬性。等同于"-rtopgDl"。 -r --recursive:遞歸到目錄中去。 -t --times:保持mtime屬性。強(qiáng)烈建議任何時候都加上"-t",否則目標(biāo)文件mtime會設(shè)置為系統(tǒng)時間,導(dǎo)致下次更新:檢查出mtime不同從而導(dǎo)致增量傳輸無效。 -o --owner:保持owner屬性(屬主)。 -g --group:保持group屬性(屬組)。 -p --perms:保持perms屬性(權(quán)限,不包括特殊權(quán)限)。 -D :是"--device --specials"選項(xiàng)的組合,即也拷貝設(shè)備文件和特殊文件。 -l --links:如果文件是軟鏈接文件,則拷貝軟鏈接本身而非軟鏈接所指向的對象。 -z :傳輸時進(jìn)行壓縮提高效率。 -R --relative:使用相對路徑。意味著將命令行中指定的全路徑而非路徑最尾部的文件名發(fā)送給服務(wù)端,包括它們的屬性。用法見下文示例。 --size-only :默認(rèn)算法是檢查文件大小和mtime不同的文件,使用此選項(xiàng)將只檢查文件大小。 -u --update :僅在源mtime比目標(biāo)已存在文件的mtime新時才拷貝。注意,該選項(xiàng)是接收端判斷的,不會影響刪除行為。 -d --dirs :以不遞歸的方式拷貝目錄本身。默認(rèn)遞歸時,如果源為"dir1/file1",則不會拷貝dir1目錄,使用該選項(xiàng)將拷貝dir1但不拷貝file1。 --max-size :限制rsync傳輸?shù)淖畲笪募笮 ?梢允褂脝挝缓缶Y,還可以是一個小數(shù)值(例如:"--max-size=1.5m") --min-size :限制rsync傳輸?shù)淖钚∥募笮 _@可以用于禁止傳輸小文件或那些垃圾文件。 --exclude :指定排除規(guī)則來排除不需要傳輸?shù)奈募?--delete :以SRC為主,對DEST進(jìn)行同步。多則刪之,少則補(bǔ)之。注意"--delete"是在接收端執(zhí)行的,所以它是在:exclude/include規(guī)則生效之后才執(zhí)行的。 -b --backup :對目標(biāo)上已存在的文件做一個備份,備份的文件名后默認(rèn)使用"~"做后綴。 --backup-dir:指定備份文件的保存路徑。不指定時默認(rèn)和待備份文件保存在同一目錄下。 -e :指定所要使用的遠(yuǎn)程shell程序,默認(rèn)為ssh。 --port :連接daemon時使用的端口號,默認(rèn)為873端口。 --password-file:daemon模式時的密碼文件,可以從中讀取密碼實(shí)現(xiàn)非交互式。注意,這不是遠(yuǎn)程shell認(rèn)證的密碼,而是rsync模塊認(rèn)證的密碼。 -W --whole-file:rsync將不再使用增量傳輸,而是全量傳輸。在網(wǎng)絡(luò)帶寬高于磁盤帶寬時,該選項(xiàng)比增量傳輸更高效。 --existing :要求只更新目標(biāo)端已存在的文件,目標(biāo)端還不存在的文件不傳輸。注意,使用相對路徑時如果上層目錄不存在也不會傳輸。 --ignore-existing:要求只更新目標(biāo)端不存在的文件。和"--existing"結(jié)合使用有特殊功能,見下文示例。 --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:DEST

    3. 本地主機(jī)通過網(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ì)是通過管道通信,即使是遠(yuǎn)程shell。而方式(3)則是讓遠(yuǎn)程主機(jī)上運(yùn)行rsync服務(wù),使其監(jiān)聽在一個端口上,等待客戶端的連接。

    路徑的格式可以是本地路徑,也可以是使用user@host:path或user@host::path的遠(yuǎn)程路徑,如果主機(jī)和path路徑之間使用單個冒號隔開,表示使用的是遠(yuǎn)程shell通信方式,而使用雙冒號隔開的則表示的是連接rsync daemon。另外,連接rsync daemon時,還提供了URL格式的路徑表述方式rsync://user@host/path。

    4. 遠(yuǎn)程shell臨時啟動一個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ī)上事先啟動rsync服務(wù),而是臨時派生出rsync daemon,它是單用途的一次性daemon,僅用于臨時讀取daemon的配置文件,當(dāng)此次rsync同步完成,遠(yuǎn)程shell啟動的rsync daemon進(jìn)程也會自動消逝。此通信方式的命令行語法格式同"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 # 拷貝源路徑較長,但只保留一部分目錄結(jié)構(gòu),使用一個點(diǎn)代表相對路徑的起始位置 rsync -R -r /var/./log/anaconda /tmp # 對遠(yuǎn)程目錄下已存在文件做備份,備份后綴為"~",使用"--suffix"指定后綴 rsync -R -r --backup /var/./log/anaconda /tmp # 指定備份文件保存路徑,默認(rèn)將不會加備份后綴,使用"--suffix"顯式指定后綴 rsync -R -r --backup --backup-dir=/tmp/log_back /var/./log/anaconda /tmp # .指定ssh連接參數(shù),如端口、連接的用戶、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

    如果僅有一個SRC或DEST參數(shù),則將以類似于"ls -l"的方式列出源文件列表(只有一個路徑參數(shù),總會認(rèn)為是源文件),而不是復(fù)制文件。

    源路徑如果是一個目錄的話,帶上尾隨斜線和不帶尾隨斜線是不一樣的,不帶尾隨斜線表示的是整個目錄包括目錄本身,帶上尾隨斜線表示的是目錄中的文件,不包括目錄本身。

    # 在/tmp目錄下創(chuàng)建etc目錄 [root@xuexi ~]# rsync -a /etc /tmp # 不會在/tmp目錄下創(chuàng)建etc目錄,源路徑/etc/中的所有文件都直接放在/tmp目錄下 [root@xuexi ~]# rsync -a /etc/ /tmp

    參考資料

  • 酷殼-RSYNC 的核心算法:https://coolshell.cn/articles/7425.html
  • The rsync algorithm:https://rsync.samba.org/tech_report/tech_report.html
  • 博客園-rsync(一):基本命令和用法:http://www.cnblogs.com/f-ck-need-u/p/7220009.html
  • 博客園-man rsync翻譯(rsync命令中文手冊):?http://www.cnblogs.com/f-ck-need-u/p/7221713.htmlThe rsync algorithm博客園-man rsync翻譯(rsync命令中文手冊):?http://www.cnblogs.com/f-ck-need-u/p/7221713.html
  • 總結(jié)

    以上是生活随笔為你收集整理的rsync算法原理及使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。