天天看點

資料密集型應用系統設計--資料複制簡介主節點與從節點複制滞後多主節點無主節點

簡介

引入資料複制的原因:

  1. 資料距離使用者更近,讓使用者通路延遲降低
  2. 提高容錯機制,某個節點壞掉後,其備份節點仍然能提供服務
  3. 負載擴充到多台機器,提高吞吐量

複制技術的真正難點在于如何處理持續變更的資料。

主節點與從節點

主從複制:

  1. 指定某個副本作為主副本,用戶端全部寫入主副本,更新主副本本地存儲。
  2. 主副本把資料發送給從副本,從副本嚴格按照主副本發來的操作順序,操作本地存儲的資料
  3. 用戶端可以從所有的副本中讀取資料

同步複制: 主節點發送給從節點資料後,需要等從節點回複

異步複制: 主節點發送給從節點資料後,不必等從節點回複

同步複制,如果由于某些原因,導緻主節點一直沒有收到從節點的回複,那麼後續的複制操作會阻塞。不過,同步複制邏輯簡單,主節點發生故障後,任何一個從節點都可以當主節點。

異步複制,IO 非常高效,但是從節點會存在資料滞後的問題,主節點挂掉後,資料丢失。

半同步複制:有一個從節點保持和主節點同步操作,其餘的從節點才用異步操作。相當于有個備份的主節點

配置新的從節點: 主節點定時 dump 資料快照,在下一次 dump 資料快照之前,保留更改的記錄檔。新的從節點加入後,先發送資料快照,然後再發送更改日志即可。像 redis 之類的備份操作,都是這麼做的。

實作複制日志:

  1. 基于語句的複制:複制

    INSERT DEL

    等更改語句,然後把對應的語句發送給從節點。實作簡單,但是缺陷在于

    RNAD NOW

    等與環境有關的指令沒有意義。
  2. 基于 WAL 預寫日志:對于 SSTable 或者 LSMT 的方式,保留 追加的 write 日志,然後發送給從節點即可。适用于追加模式的資料庫。
  3. 基于行的邏輯日志複制:類似于 MySQL 的 binlog,複制與存儲分離。

複制滞後

複制滞後的問題,一般是暫時的,異步複制最終會一緻,稱之為『最終一緻性』

**讀自己的寫:**寫入主副本,但是讀的從副本還沒同步完資料

**單調讀:**使用者擷取的資料的時間戳順序不對。比如 A、B、C 3個對等機器,使用者的請求路由到了3個機器上,A 中存在 x 使用者的評論,但是 B C 中沒有,A 傳回了結果,B、C 也傳回了結果,但是 B、C 的結果覆寫了 A 的結果,導緻使用者看到的評論消失了。

**字首一緻性:**使用者擷取的資料的時間戳是亂序的

多主節點

多個主節點,每個主節點同時是其他主節點的從節點。這些主節點,有自己的私有從節點。

場景:

  1. 多個資料中心同步資料
  2. 使用者多個裝置,比如一個使用者有mac、iphone 和 ipad 這樣的場景。這些裝置可以離線
  3. 協作編輯

多主節點最難解決的是寫入沖突的問題,一般來說最佳方案是避免沖突,其餘方案這裡暫時不涉及。

多主節點的拓撲結構:

  1. 環狀拓撲
  2. 星式拓撲
  3. p2p 模式

    1和2的模式,最麻煩的地方在于關鍵路徑損壞的話,會幹擾整個叢集的同步

無主節點

無主節點的方式,放棄主節點,允許用戶端直接寫入所有的結點。

用戶端寫入的時候,向多個副本寫入資料。讀取的時候,從多個副本讀取。

  1. 讀修複:假設某個節點下線後重新上線,其中的資料落後其他副本。則讀取的時候,用戶端會使用其他副本的資料,并更新目前落後節點的資料
  2. 反熵過程:用戶端讀取的時候,把其他副本中存在的資料,寫入一個或者多個不存在資料的副本

假設 w 是一次性寫入的副本個數,r 是一次性讀取的副本的個數,n 是總的節點的個數,那麼需要滿足:w + r > n

w + r > n 通常可以配置,可以計算能容忍的壞節點的個數。

w + r 風格的局限性:

  1. 同時寫入的情況,無法确認先後順序
  2. 讀寫同時發生時,讀的資料可能仍然是就值,因為寫操作可能隻是發生了一部分
  3. 某些副本寫失敗,整體操作認為失敗,但是仍然有部分節點是成功的,此時讀髒資料

繼續閱讀