MySQL-04-分佈式

分佈式系統已經無處不在,它有哪些特性?在 MySQL 應用過程中的表現形式是什麼樣的?分佈式 MySQL 的數據質量怎麼保障?這裏做一些介紹和總結。

分佈式理論基石 CAP
  • 一個分佈式系統最多隻能同時滿足 CAP 這三項中的兩項,以分佈式關係型數據庫舉例說明:
    • Consistency 一致性:一個事務在一個節點提交後,在同一時間所有節點讀出來的數據是一致的;
    • Availability 可用性:系統中任何一個節點故障,不影響整體繼續提供服務;
    • Partition Tolerance 分區容錯性:當系統內部出現網絡故障,所有節點仍然都可用,但是內部出現腦裂,此時也不影響一致性。
  • CAP 在本質上,是分佈式系統設計過程中需要考慮的最基本的三個問題。
  • 雖然沒有完美的 CAP,但是,在實際業務場景中,我們可以根據業務場景的實際需求,有取捨的進行分佈式系統的設計,給用戶一個完美的體驗
  • 例如,對於一致性問題,節點間的網絡延遲和對性能的要求是現實存在的矛盾點和難點,因此,在實現過程中出現了強一致性、弱一致性和最終一致性。
必備利器 ZooKeeper
  • ZooKeeper 是一個分佈式協調服務
    • 可以有非常多的應用:發佈訂閱、命名服務、分佈式協調和分佈式鎖
    • 基於 Fast Paxos 思想實現,是對 Basic Paxos 算法的優化
    • 服務方式爲 Server/Client 模式
    • 允許分佈式進程通過 Client 共享 Server 中的層次結構命名空間,從而實現相互協調,命名空間與標準文件系統類似 /zoo-1/tiger,稱爲 ZNode
    • ZNode 分爲持久節點和臨時節點兩類,其中臨時節點的生命週期和 session 綁定,一旦 session 失效,那麼臨時節點會被移除
    • ZNode 支持自動編號功能,這種 ZNode 節點會根據當前已近存在的 ZNode 節點編號自動加 1
    • ZNode 操作包括:CREATE/DELETE/READ/WRITE
    • ACL 權限控制包括: CREATE/DELETE/READ/WRITE/ADMIN
  • Fast Paxos 中的角色分類:領導者(Leader)、跟隨者(Follower)、觀察者(Observer),Leader 的選舉流程如下:
    1. 每個Server發出一個投票。每次投票會包含所推舉的服務器的(myid, ZXID),然後各自將這個投票發給集羣中其他機器。
    2. 接受來自各個服務器的投票。集羣的每個服務器收到投票後,首先判斷該投票的有效性,如檢查是否是本輪投票、是否來自LOOKING狀態的服務器。
    3. 處理投票。針對每一個投票,服務器都進行比較,比較的規則是:優先選擇 ZXID 更大的,然後選擇 myid 較大的。
    4. 統計投票。每次投票後,服務器都會統計投票信息,如果確認已經有過半機器接收到相同的投票信息,則確認 Leader。
    5. 改變服務器狀態。一旦確定了 Leader,每個服務器就會更新自己的狀態,如果是Follower,那麼就變更爲 FOLLOWING,如果是 Leader,就變更爲 LEADING。
  • Fast Paxos 中事務的請求和提交的流程如下:
    1. 發起投票。若當前請求是事務請求,Leader 會發起一輪事務投票,在發起事務投票之前,會檢查當前服務端的 ZXID 是否可用。
    2. 生成提議 Proposal。若 ZXID 可用,ZooKeeper 會將已創建的請求頭和事務體以及 ZXID 和請求本身序列化到 Proposal 對象中,此 Proposal 對象就是一個提議。
    3. 廣播提議。Leader 以 ZXID 作爲標識,將該提議放入投票箱 outstandingProposals 中,同時將該提議廣播給所有 Follower。
    4. 收集投票。Follower 接收到 Leader 提議後,進入 Sync 流程進行日誌記錄,記錄完成後,發送 ACK 消息至 Leader 服務器,Leader 根據這些 ACK 消息來統計每個提議的投票情況,當一個提議獲得半數以上投票時,就認爲該提議通過,進入 Commit 階段。
    5. 將請求放入 toBeApplied 隊列中。
    6. 廣播 Commit 消息。
MySQL 應用中的分佈式情況

  信息化和數字化的腳步勢不可擋,數據庫爲了不成爲業務發展的瓶頸,其不斷擴容的過程,也是分佈式技術逐步深入數據庫領域的過程。

  • 一、 存儲空間和讀寫流量擴展:分庫分表
    • 如果一個電商平臺穩健發展的話,訂單數據是比較容易出現數據量大的問題,所以需要對它進行拆分。
    • 此時從理論上對訂單拆分有兩個維度,一個是訂單的 id 取模的方式,即以訂單 id 爲分庫分表鍵。另一個是通過賣家用戶 id 進行取模,即以賣家用戶 id 爲分庫分表鍵。
    • 如果是按照訂單 id 取模,比如按照 64 取模,則可以保證主訂單以及相應的子訂單,和詳情數據平均落入 64 個數據庫中。
    • 如果按照賣家用戶 id 取模的方式,比如也是按照 64 取模,也能夠保證訂單相關數據拆分到 64 個數據庫中。但如果有些賣家的交易量很大,就會出現數據不平均的現象。
  • 二、 多維度查詢擴展:異構索引表
    • 按照訂單 id 取模雖然很好地滿足了訂單數據均勻地保存在數據庫中,但在買家查看自己訂單的業務場景中,就出現了掃描所有的 64 個分庫然後聚合結果的情況,嚴重影響效率。
    • 採用“異構索引表”的方式解決,即採用異步機制將原表的每一次插入或更新,都以另一個維度(買家 id 取模分庫)保存一份完整的數據表,並構建相應的索引,這是拿空間換時間的典型思路。
    • 應用向以訂單 id 分庫分表的數據庫插入或更新一條數據時,也會再保存一份到以買家 ID 分庫分表的數據庫,其結果就是同一條訂單數據在兩個數據庫中同時存在,這就是給訂單創建了異構索引表。
  • 三、 單點讀流量擴展:一主多備
    • 在讀流量極大的情況下,需要這種一個主庫(提供數據更新服務)多個備庫(提供數據查詢服務)的結構,尤其適用於寫流量非常少,讀流量非常大的配置數據庫
  • 四、 異地容災和就近訪問:單元化
    • 單元化核心設計思想是從 C 端用戶角度考慮,將用戶核心業務的閉環鏈(比如購物閉環),內聚到一個單元,用戶在 C 端操作的一個完整過程,相關數據都能在一個單元內完成,避免跨單元獲取數據。這裏的一個單元可以是一個機房,也可以是一個機房內的某一組子系統羣。
    • 可以按照一定的路由規則(按照用戶 id 或者活用的地理位置),讓某些用戶的訪問請求在某個單元閉環完成,例如,深圳附近的用戶的所有訪問請求都在深圳單元,實現就近訪問。
    • 單元化使整體系統具備了極強的水平伸縮能力,
    • 異地多活怎麼去應對故障
  • 五、 分佈式數據庫
    • 分佈式事務
    • 分佈式存儲
數據質量問題

  數據質量面臨的挑戰是,在分佈式部署場景下的,最終一致性的保障。我們假設,單元間的數據同步也是基於 binlog 的異步複製,數據同步方式如下圖。
圖片替換文本

  • 單元內的情況,某個單元發生網絡故障時,單元內主庫備庫的數據一致性問題

    • 異步複製和孤島雙寫導致老主庫多數據,同時回補時由於自增 ID 或狀態推進導致無法自動修復
  • 單元間的情況,某個單元發生網絡故障,由此產生的單元間的數據一致性問題

    • 單元 2 中主備切換後,中心向新主庫複製數據時,無法獲取準確的位點,往往會產生偏差。
    • 自動修復和單元間同步交叉使用 binlog 的數據,導致單元間不一致
    • 自動修復,導致依賴 binlog(例如異構表) 的應用獲得髒數據
基於 binlog 的自動修復
  • 針對老主庫多數據的情況,解析 binlog 獲得可執行 SQL 語句
    • 在老主庫反向執行 SQL 完成回滾(執行時必須關閉 binlog),使主備數據一致
    • 在新主庫正向執行 SQL 實現回補,儘量修復數據
  • 不足
    • 事後的回補由於主鍵衝突等原因可能回補失敗,導致丟數據
    • 回滾很難支持 DDL/TRUNCATE 語句
    • 回滾不記錄 binlog,會導致單元間的不一致
數據校驗和修復
  • 增量數據校驗
    • 從業務層接收異步消息,獲取用戶 id、訂單 id 等鍵值,對比單元內主備和單元間的數據
    • 修復方式:記錄不一致的情況,根據業務場景選擇以某個節點數據去訂正其他節點
    • 缺點:無法保證全局的一致性
  • 全量數據校驗
    • 使用全量校驗程序,全量對比某兩個節點的數據
    • 修復方式:把記錄不一致的情況同步給增量校驗的後臺,利用增量校驗的修復邏輯,結合業務場景修復
    • 缺點:全量校驗比較耗時,查詢使用的是 MySQL 快照讀,可能會導致 undo log 無法及時回收,佔用系統資源,只能在業務低峯期執行
強同步、半同步和強保護模式介紹

  如果主備之間使用 XA 強同步(打開 sync_binlog),數據質量問題會得到極大的環節,但是對性能卻是無法接受的。

  • semi-sync (半同步)
    1. 半同步介於異步和全同步(sync_binlog 打開)之間
    2. 主庫只需要等待至少一個從庫節點收到並且 Flush Binlog 到 Relay Log 文件即可
    3. 半同步保證了主備的最終一致性,同時降低了主庫事務 commit 的等待時間
    4. 半同步中主庫在提交事務前會等待備庫的 ack 信號,必須設置等待超時,在超時後,會退化到異步模式
  • MP(強保護模式)
    1. 強保護模式是基於半同步模式的改進,區別在於等待備庫 ack 超時後的處理方式
    2. MP 在超時後,會設置 read_only=1,使主庫不能寫入新數據,以此強制保護主備一致性
  • 半同步(semi-sync)模式和強保護(MP)模式的不足
    • 主備間網絡抖動和備庫故障都會影響可用性
    • 高 tps 情況下 semi-sync 對 rt 有明顯影響
參考文檔

https://blog.csdn.net/u014231523/article/details/88096413
http://www.warski.org/blog/2011/07/trying-to-understand-cap/
https://www.cnblogs.com/paul8339/p/9178761.html
https://blog.csdn.net/qq_27384769/article/details/80331540

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