數據同步原理

數據同步

原文: https://www.objc.io/issues/10-syncing-da...git

關於

這裏的數據同步的問題描述的是-多個不一樣的端存儲相同的數據,並須要保證數據的同步。 這在現實開發中實在是個使人頭疼的難題, 參考原文在理解的基礎上作了修改和調整算法

  1. 分佈式數據庫互備數據庫

  2. 分佈式應用配置同步服務器

  3. 多設備應用數據同步微信

本文想借此展開相關的理論和實例來深刻研究一下數據同步問題。網絡

數據同步理論

同步方式

同步客戶端服務器 (Synchronous Client-Server, S-CS)
應用直接和遠程服務通信,將數據同步框架

實例:微信發送一條消息,只有消息發送完成事後纔會存儲在本地消息發送成功列表中,未發送成功會提示從新發送異步

異步客戶端服務器 (Asynchronous Client-Server, A-CS)
應用將數據保存在本地,應用保持本地數據和遠程數據的同步(後臺運行) 分佈式

實例:Mac QuickTime 錄製了一段視頻,存儲在文件系統中,iCoud 自動將文件系統中的數據同步到雲端ide

異步對等方式 (Asynchronous Peer-to-Peer, A-P2P)
應用數據保存在本地,應用保持本地數據和其餘端的數據同步, 每一個端存儲數據的完成備份,服務器端不存在備份。

數據同步要素

識別
對象識別須要使用全局標識符 uuids (universaaly Unique identifiers)

變化追蹤
描述算法如何肯定自上一次數據同步後, 數據發生了哪些變化, 而後本地存儲應該如何修改。

  1. 顆粒大小: 當某個屬性字段被修改事後,肯定追蹤這個字段仍是追蹤整個實例

  2. 記錄變化: 是否變化簡單狀況能夠用一個 Boolean 的標示來表示, 也可能須要用日誌來記錄變化並附加時間戳

  3. 軟刪除
    衝突解決

當多端都在共同修改一個實例的時候,就會出現衝突。

  1. 簡單狀況: 讀寫被認爲是原子操做,解決衝突能夠當作選擇什麼版本的存儲。 如 iCloud 出現衝突時,應用提示用戶選擇文檔的什麼版本

  2. 變化優先級策略:

    • 最近一次的同步操做肯定級別最高, 全部這一次同步操做的變化覆蓋以前存儲的數據,

    • 最近一次修改時間戳肯定優先級別

  3. 避免隨機策略,老是保證一致的選擇策略

對等同步通信(S-P2P)

假設咱們有一個像 iTunes 那樣的 Mac 應用程序,它能夠經過 USB、藍牙或者 Wi-Fi 和 iPhone 進行同步通信。(憑藉快速的本地網絡,咱們不用太在乎限制數據傳輸大小)

  1. 第一步: 當 iPhone 第一次同步的時候,兩個應用程序經過 Bonjour 發現對方,而後 Mac 應用程序將它的全部存儲數據壓縮,經過套接字將壓縮後的文件傳遞給 iPhone 應用程序,而後 iPhone 將其解壓並安裝。

  2. 第二步: 如今假設用戶使用 iPhone 對已經存在的對象作了修改 (好比,給一首歌打了星級)。該設備上的應用程序給該對象設置了一個 Boolean 型的標記(好比,changedSinceSync),用來表示該對象是新的仍是已經被修改過的。

  3. 第三步:當下一次同步發生的時候,iPhone 應用程序將它的全部數據存儲壓縮並回發給 Mac。Mac 裝載這些數據,尋找被修改的實例,而後更新它本身對應的數據。而後 Mac 又將更新後的數據存儲的完整拷貝發送給 iPhone,用來替代 iPhone 已經存在的數據存儲,而後整個流程又從新開始。

總結來講,同步操做須要設備可以向其餘設備傳輸數據,而且可以決定哪些被修改、合併,而後回傳更新後的數據。 保證了這兩個設備同步以後具備相同的數據,因此,有很強的健壯性。

客戶端-服務器同步通信(S-CS)

當加入了服務器的時候,服務器是爲了可以更加靈活地同步數據,可是它是以數據傳輸和存儲爲代價的。 須要儘量地減小通信開銷,因此來回地拷貝整個數據是不可行的。

  1. 前置條件:假設數據存儲在服務器上的數據庫中,而且每個對象都有一個最後更新的時間戳。

  2. 第一步:當客戶端程序第一次同步的時候下載全部的數據,而後創建一個本地存儲,同時也在本地記錄同步的時間戳。

  3. 第二步:當客戶端程序發生改變的時候,它會更新對象的最後更新時間戳。

  4. 第三步:當下一次同步發生的時候,客戶端會決定自上一次同步後,哪些對象作了修改,而後僅把被修改的對象發送給服務器。服務器會合並這些修改。若是服務器對某一個對象的拷貝被另外一個客戶端作了修改,那麼它會以最近的時間戳爲準來保存修改。而後服務器會回傳全部比上一次從客戶端發來的時間戳新的變化。這須要考慮到合併的問題,刪除全部覆蓋的變化。

也許有不少不一樣的方法。好比,你能夠爲每個屬性引入一個時間戳,而後在屬性粒度級去追蹤變化。或者你能夠在客戶端合併全部的數據,而後將合併後的結果發回給服務器,這其實是互換了角色。可是,基本說來,一個設備發送修改結果給其餘設備,而後接收方合併並回發合併後的結果。

刪除須要考慮更多。由於一旦刪除了一個對象,就不可能跟蹤它了。一種選擇是使用 軟刪除 ,也就是對象並非被真正的刪除,而是標記爲刪除 (好比使用一個 Boolean 屬性)。 (這和在 Finder 中刪除一個文件相似。只有當你清空的垃圾桶以後,它才被永久地刪除。)

客戶端-服務器異步通信 (A-CS)

異步的數據同步框架和服務的吸引力在於它們提供了現成的解決方案。 S-CS 模式是要定製的,也就是說得爲不一樣的應用程序以及不一樣的平臺編寫不一樣的代碼。

異步服務 (好比, Dropbox Datastore API 和 Wasabi Sync) 一般提供框架,讓應用程序開發者用起來好像是本地數據存儲。這些框架在本地保存修改,而後在後臺控制與服務器的同步。

A-CS 和 S-CS 的一個最主要的區別在於,A-CS 框架額外提供的抽象層,屏蔽了直接參與同步的客戶端代碼。這也意味着,同一服務能夠用於全部的數據模型,而不是特定的一種模型。

數據同步實例

  1. 數據庫互備

  2. Evernote

  3. workflowy

  4. 部落衝突

  5. 百度雲盤

  6. 通信錄備份

  7. git

相關文章
相關標籤/搜索