增量更新同步 檔案增量同步之rsync演算法

2021-10-14 18:46:04 字數 1791 閱讀 9540

之前畢設有用到檔案增量同步,於是乎就記錄一下。

在a和b兩個不同端之間有相似度很高的檔案,同時這個檔案又比較大。如果通過全量傳輸來更新,http傳輸量很大,非常不友好。那麼可以通過某些手段,只上傳修改的內容,其餘內容復用舊檔案。

對於a、b檔案進行同步為例,首先對a檔案進行分塊,並且對每一塊進行摘要計算(弱摘要&強摘要),並將其摘要資料傳輸給b端。b從第一位元組開始,以相同大小的塊滑動下去一一比較。

首先計算當前塊的弱摘要,若弱摘要命中,則計算強摘要是否相同;若均相同,則該區域是相同塊;兩個相同塊之間的區域,則是差異塊。

(**於網路)

那麼以上的內容,其實對於a、b兩端,均有計算量。其實是不友好的,在單a對多b或者單b對多a的場景,則壓力過大。

同時滑動塊的大小也非常影響結果:若滑動塊過小,可以提高命中率,但是計算量增大;若滑動塊過大,計算量減少,但是可能降低命中率。

對於實際的應用場景,可以大致分成兩種情況:

無論是第一種情況還是第二種情況,我們都希望將計算量放到客戶端,而服務端僅僅做合併操作或者傳輸資料操作。

那麼我們可以在其他端第一次傳輸給服務端新檔案的時候,將摘要在本地計算得到,然後一起發給服務端。在之後更新的時候,同時也把新的摘要發給服務端更新。服務端就可以快取摘要內容,省去計算過程。

同時,對於某些情況,可以快取新舊檔案的差異內容,通過版本號的差異,查詢服務端是否有儲存差異內容檔案,若儲存了,則可以直接傳輸更新。

那麼對於第一種情況:客戶端首先向服務端發起獲取摘要請求,服務端返回摘要後,客戶端本地滑動塊檢測摘要,然後,將檢測結果同差異內容檔案傳送給服務端,服務端做合併操作。

對於第二種情況:客戶端還是向服務端發起獲取摘要請求,服務端返回摘要後,客戶端滑動塊檢測摘要。相同塊內容,則從本地檔案獲取,差異塊內容檔案則通過http range請求。其實也可以直接請求差異檔案,若服務端有儲存的話。

同時需要設定闕值,在塊滑動檢測時,若命中率過低,可以省去檢測過程,直接採用全量上傳檔案同步操作。因為,相似度低的檔案,滑動檢測比較花時間,同時結果也不盡人意。

以瀏覽器新檔案增量同步給服務端為例。

我們可以建立乙個webwork,然後將計算摘要的過程和滑塊檢測的過程,都放到webwork上。

由於摘要結果需要三個資料,弱摘要強摘要以及對應序號。一開始想的是陣列,物件包括兩種摘要,下標作為序號。但是,這樣查詢效率太低了,每次查詢都需要遍歷一遍,效率低下。

後來換了個思路,採用以下資料結構:

弱摘要作為key值,強摘要作為value值,對應的原檔案內容序號則以@index放到value的末尾。同時,因為弱摘要是可能出現重複的,所以,在計算時,檢測弱摘要是否存在,若存在則在末尾加@1,若還存在則,繼續@2等等,直到不存在,可以放入物件中。

目的就是為了降低查詢複雜度,從o(n)變成o(1)。

同時,對於相似度高的檔案,滑動塊檢測,必然出現連續的相同塊。 若連續區域,在原檔案上是連續的序號,則可以將其合併,減小傳輸資料大小:

null是差異塊檔案,下標作為檔案的標識之一。

num是原檔案分塊結果的第num塊區域。

陣列是原檔案分塊結果的第start至end區域。

然後,對於差異塊檔案,就進行正常上傳操作,目前還是以http1.1為主流,還是採用4~5個4~5個同時上傳比較好。

本文原始碼:

Linux rsync增量同步方法

可以先使用 rpm qa grep rsync 檢視rsync是否已經安裝 下面說說rsyns的配置過程 一.配置伺服器端 首先編輯 etc rsyncd.conf 內容如下 uid nobody 進行備份的使用者 nobody為任何使用者 gid nobody 進行備份的組 nobody為任何組 ...

MySQL 備份 增量同步

mysql增量同步主要使用binlog檔案進行同步,binlog檔案主要記錄的是資料庫更新操作相關的內容。1.備份資料的意義 針對不同業務,7 24小時提供服務和資料的重要性不同。資料庫資料是比較核心的資料,對企業的經營至關重要,資料庫備份顯得尤為重要。2.備份資料庫 mysql資料庫自帶的備份命令...

如何實現檔案增量同步 演算法

問題 如何增量同步檔案,例如乙個文字檔案有10m,分別存放在a,b兩個地方,現在兩個檔案是完全一樣的,但是我馬上要在a上對這個檔案進行修改,b如何實現自動和a上的檔案保持一致,並且網路的傳輸量最少。應用場景 這樣的使用場景太多,這裡隨便列舉幾個 1.a機器為線上運營的機器,現在需要一台備份的機器b,...