分佈式數據系統——DDIA(二)

數據複製

目的

  • 高可用。容忍單個副本故障、網絡分區。
  • 可擴展。多副本提高讀吞吐量。
  • 低延時。距用戶較近,交互更快。

主從複製

  • 寫:主節點。讀:從節點。
    200329.lead.follower.png
  • 到主節點網絡問題影響所有寫入。

複製形式

  • 同步複製。從節點確認寫入後返回。
    • 從節點數據最新版本,可瞬間故障切換。
  • 異步複製。從節點無需確認。
    • 從節點不會影響主節點吞吐量。
  • 半同步複製。一個從節點同步,其餘異步。

複製日誌

  • 基於語句。INSERT等。
    • 非確定性語句,now等執行結果不同。
    • 依賴現有數據的操作,如UPDATE,需要保證副本按照相同順序執行。
  • 基於物理日誌WAL,如redo。
    • 和存儲引擎耦合,偏底層。如果存儲格式不前後兼容,無法滾動升級。
  • 基於邏輯日誌,如binlog。
    • 複製和存儲邏輯解耦。向後兼容,方便異構數據。
    • 包含行前後值。記錄因果關係,處理併發。
  • 基於觸發器
    • 靈活但是增加數據庫壓力。

運維變更

  • 新增從節點。
    • 一致性快照 -> 複製日誌追趕變更。
  • 從節點失效。根據複製日誌追趕式恢復。
  • 主節點失效。節點切換。
    1. 確認主節點失效。如心跳超時。
    2. 選新的主節點。選舉->共識算法推送,節點和主節點差異小優先。
    3. 新主節點生效。寫請求轉發,原主節點恢復後降級成從節點。
  • 節點切換風險。
    1. 腦裂。老主節點上線未失效,寫衝突。
    2. 數據丟失。異步複製從節點落後,如果外部依賴這部分數據,危險。
    • 使用自增主鍵,外部映射到該主鍵關係錯誤。
    1. 頻繁切換。超時時間選取,可使用手工切換。

副本一致性

  • 讀寫一致。從節點讀到自己主節點寫的數據。
    • 從主節點讀取用戶可能修改的數據。
    • 讀取時帶時間戳(版本號或時鐘),副本需要覆蓋寫入的時間戳,否則重選副本。
  • 單調讀一致。讀到新版本後不再讀到舊版本。
    • 根據用戶id路由指定副本。
  • 因果一致。先發生先讀。
    • 有因果關係的寫入從一個副本讀。
    • happens-before追蹤因果。

多主複製

200329.mulleader.png

適用場景

  • 多數據中心。
    • 性能。就近寫,不用跨廣域網。
    • 容錯。切換數據中心。
      • 數據中心失效。
      • 到數據中心的網絡失效。
  • 離線客戶端。等價於單節點數據中心+極不可靠的網絡。
  • 協作編輯。

處理寫衝突

異步檢查:主節點各自寫入的優勢。
同步檢查:簡單。

  • 避免衝突。用戶路由到單節點寫,但漫遊或網絡故障可能重新路由產生衝突。
  • 收斂於一致。
    • 最後寫入者獲勝(LWW)。
      • 保留寫入版本號最大記錄。
      • 保留節點版本號最大記錄。
    • 合併併發寫入,依賴應用層(自動)、用戶(手動)解決衝突。
      • 版本號標記操作的因果關係。

無主複製

  • 用戶寫入多個節點並從多個節點讀取。
    200402.leaderless.png
  • 通過數據版本號確認最新的有效值。

quorum一致

  • 讀寫quorum。n個節點,w個寫入確認,r個讀取,w+r>n保證讀寫節點有重合,可以讀到最新值。
  • 讀修復。讀取到舊版本回寫新版本。
  • 反熵。後臺進程check更新數據版本。

quorum一致侷限

部分成功、複製滯後導致。

  • 讀寫併發。寫操作部分完成,讀取不確定。
  • 部分寫失效。寫操作成功數<w,操作失敗但是能讀取新值。
  • 寬鬆quorum條件無法保證讀寫節點有重合。
    • 網絡分區導致可達節點<w個,臨時節點暫存數據,保證總共寫入w個,網絡問題解決後數據回傳。

數據分區

  • 目的:提高擴展性,大數據集分散在多個節點上,分擔查詢負載。
  • partition同義詞。
    • shard:ES,MongoDB
    • region:Hbase
    • tablet:Bigtable
    • vnode:Cassandra

分區方式

  • 基於關鍵字分區。
    • 區間查詢特性良好。每個分區可以關鍵字順序查找。
  • 基於關鍵字hash分區。
    • 數據均勻分佈。特定模式會數據傾斜,造成熱點。
  • 折中。如Cassandra。
    • 複合主鍵第一列可hash分區,其他列用作SSTable的排序。
    • 第一列分佈均勻,其他列支持區間查找。

二級索引

  • 基於文檔。利於寫,ES、Cassandra。
    • 本地索引。每個分區獨立,維護自己的二級索引。
    • 並行查詢,讀延遲放大。
  • 基於詞條。利於讀。
    • 分區的全局索引。
    • 單個文檔更新,如果涉及多個不同分區的二級索引,寫放大顯著,通常異步。

分區再平衡

  • 原因:
    • 查詢壓力增加,需要更多CPU。
    • 數據規模增加,需要更多硬盤。
    • 節點故障,需要其他節點接管。
  • 目標:
    • 負載、存儲在集羣中分佈均勻。
    • 平衡過程中正常提供讀寫服務。
    • 避免不必要的遷移,加快過程減少網絡磁盤I/O影響。
  • 觸發方式:
    • 自動。節點負載過重可能被認爲失效,再平衡會加重負載,可能雪崩。
    • 手動。

取模

mysql分庫分表

  • 遷移過程中數據在節點間複製,需要雙寫或者複製停寫,讀寫受影響。
  • 再平衡成本高。
    • 節點N發生變化,每個節點都有數據遷移。
    • 節點N發生多次變化,同一條數據多次遷移。

固定數量分區

ES

  • 初始創建遠超節點數的分區,節點->分區一對多。
  • 新增節點時只需要調整分區、節點映射關係。
    • 不影響節點的讀寫。
    • 成本低。

動態分區

Hbase

  • 初始預分區,或者集中在一個分區,節點->分區一對多。
  • 分區數據量大於閾值則分裂,小於閾值則合併。

按節點比例分區

Cassandra

  • 初始時每個節點具有固定數量的分區。Cassandra默認1節點->256個分區。
  • 新增節點加入時,隨機選擇現有分區分裂拿走一半數據。

請求路由

  1. 客戶端連接任意節點,節點轉發到目標節點。
  • gossip協議同步集羣狀態,如Cassandra。
  1. 客戶端連接路由層,路由層轉發到目標節點。
  • zk同步集羣狀態,如hbase、codis。
  1. 客戶端感知分區節點,直連目標節點。

事務

  • ACID
  • 事務隔離級別
  • 重試中止事務的問題:
    • 超時認爲已成功的事務未成功,重試需要保證冪等。
    • 系統負載導致錯誤,重試更糟,需要重試上限、指數回退。
    • 永久系統故障導致,重試無意義。
    • 重試有除DB外的操作,如短信,需要分佈式事務。
    • 重試失敗,需要補償。

分佈式系統問題

  • 故障->部分失效。

不可靠網絡

  • client->network->server->network->client,都有可能出問題。
    200412.unreliable.png
  • 超時是檢測故障唯一可行的方法。
  • 網絡採用分組傳輸,動態分區。是可變性和可靠性的權衡。
    • 優點是可以用較高的資源利用率應對突發流量。
    • 缺點是數據可能包擁堵排隊,造成延遲的波動,這種異步網絡的延遲是沒有上界的。

不可靠時鐘

分類

  • 牆上時鐘。絕對時鐘,可以和NTP同步。
    • System.currentTimeMillis()從1970.1.1開始的毫秒,不含閏秒。
    • 同步時如果本地時鐘遠快於NTP服務器,會直接回撥本地時鐘。
  • 單調時鐘。相對時鐘,可以測量時間間隔(超時),NTP不同步。
    • System.nanoTime

依賴時鐘的風險

  • 依賴絕對時間戳,時間不同步,可能產生因果倒序。優先考慮基於遞增計數器、時鐘置信區間。
    • LWW前因覆蓋後果。
      200419.clocklww.png
  • 依賴相對時間戳,進程暫停,產生衝突。
    • 根據時間校驗租約->暫停->處理。可能暫停完租約過期,和其他節點處理衝突。
      200419.lockexpire.png
    • 可以暫停前通知其他節點、大對象不回收定期重啓等應對進程暫停問題。

不可靠信息

真相由多數節點決定,節點不能根據自己的信息判斷自身狀態。//TODO zk故障全公司服務重啓

  • 無意誤操作。如進程暫停,進程誤以爲自己還是Master。
    • 應對:Fencing令牌,拒絕舊令牌的操作。
      200419.fencing.png
  • 拜占庭故障。如軟件bug、惡意攻擊。
    • 應對:鑑權、加密等。

抽象模型

  • 計時模型。網絡是否有上界延遲。
    • 同步模型。
    • 部分同步模型。
    • 異步模型。
  • 節點失效模型。
    • 崩潰終止
    • 崩潰恢復。
    • 拜占庭失效。

普遍情況:部分同步+崩潰恢復。

一致性與共識

  • 事務隔離:處理事務併發時的各種臨界條件。
  • 分佈式一致性:針對延遲、故障等協調副本狀態。

可線性化

  • 最強一致性模型。
  • 基本思想:一個系統看起來只有一個副本,所有操作都是原子的。
  • 使用場景:
    • 加鎖和主節點選舉。
    • 唯一性約束。主鍵、用戶名等。
    • 跨通道的時間依賴。消息消費在圖片存儲完成之後。
      200423.channel.png
  • 實現方式。考慮容錯必須多冗餘,涉及複製,只有共識算法可靠。
    • 共識算法。VSR,Paxos,Raft,Zab
    • 主從複製。從唯一節點讀取。
      • 使用快照隔離、腦裂則非線性化。
    • 多主複製。非線性化。
    • 無主複製。dynamo風格。
      • 如果網絡延遲,在寫確認之前讀取,仍然非線性化。
        200423.quorum.png

順序保證

  • 因果一致性弱於可線性化。偏序關係。
    • 因果關係可以被排序(happens-before)
    • 併發關係無法被排序
  • Lamport時間戳。
    • 唯一:計數器-存儲節點ID的鍵值對
    • 因果一致:節點追蹤並維護接觸的最大計數器,請求中帶上該計數器。
      200424.lamport.png

事務與共識

  • 共識的等價問題:
    • 線性化的CAS寄存器
    • 原子事務提交
    • 全序廣播
    • 鎖與租約
    • 成員協調
    • 唯一性約束
  • 解決方式
    • 單個主節點。
    • 主節點失效:等待恢復、認爲介入、共識算法選新主節點。
  • 共識算法的要求:
    • 安全性:
      • 協商一致性。所有節點接收相同的決議。
      • 誠實性。所有節點只能做一次決定。
      • 合法性。結論一定是某個節點提出的。
    • 活性:
      • 可終止性。少於一半節點崩潰可達成結論。

//TODO zk設計

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章