前幾日和同事聊起來數據庫分庫分表問題,於是有了此文。
起源
-
DRDS
- 數據庫中間件Cobar、MyCat、Amoeba
-
Tidb
- google spanner/F1
架構原理
- DRDS架構
- Tidb架構
分片機制
-
DRDS
- 支持HASH、RANGE_HASH、MMDD等多種分片類型
- 原理上都是基於HASH分片
- 需要在建表時指點分片key以及分片方式
- 不支持全局唯一索引
-
Tidb
- 通過multi-raft協議,將數據region(按範圍分區)分佈於不同節點,分片不需要應用干預
- 由於按照範圍對數據進行分片,在某些範圍數據被集中訪問時易造成熱點問題,業務上可以通過對主鍵進行散列編碼打散數據或者熱點數據通過cache方式解決該問題
應用限制
- DRDS
- Sharding 後對應用和 SQL 的侵入都很大,需要 SQL 足夠簡單,這種簡單的應用導致 DB 弱化爲存儲。
- SQL 不能跨維度 join、聚合、子查詢等。
- 每個分片只能實現 Local index,不能實現諸如唯一鍵、外鍵等全局約束。
- Tidb
- 不支持外鍵
- 自增主鍵保證唯一但不保證連續
支持的事務模型
- DRDS
- DRDS本質上是DB proxy,事務基本上是指proxy層的事務,原則上並不涉及RDS數據庫級別的事務
- FREE:允許多寫;不保證原子性;無性能損耗;數據批量導入、表初始化等場景
- 2PC:兩階段提交事務;保證原子性,不保證可見性;推薦 MySQL 5.6 用戶使用
- XA:XA強一致事務;保證原子性;保證可見性;推薦 MySQL 5.7 及更高版本用戶使用
- FLEXIBLE:柔性事務;補償型事務;適用於性能要求較高、高併發的業務場景
- Tidb
- tidb參考Percolator 事務模型,事務下沉到tikv(存儲引擎)
- 通過2PC(Prewrite階段和Commit階段)提交以及樂觀鎖保證分佈系統中的ACID
- tidb提供的事務隔離級別(Snapshot Isolation)與mysql提供的事務隔離級別保持一致
高可用保障
- DRDS
- 通過下游RDS主備方案保證數據高可用
- 數據冗餘兩副本以上,基本上從節點不參與計算只進行數據備份,資源上比較浪費
- 跨機房多地部署實施困難,需要藉助同步工具或業務上實現數據雙寫
- Tidb
- tidb的元數據存儲在pd中,通過pd調度數據分片
- 分片最低三副本,通過multi-raft調度
- 通過節點標籤影響pd調度,實現兩地三中心部署
從架構來講tidb的原生三副本機制要優於DRDS通過異步數據同步實現高可用的機制。異步同步主要的缺點是切換週期長,存在數據丟失的風險。對於DRDS當業務系統使用XA或者GTS這種強一致性協議時,某節點宕機會導致服務整體不可用
擴縮容再平衡機制
橫向擴索容主要考慮數據再平衡的效率和對在線業務系統的影響問題。考慮到DRDS分庫分表採用哈希切分,那麼在數據再平衡時需要針對分片key將所有數據進行重新分片,造成網絡及系統開銷較大;tidb採用range分片機制,當節點數發生變化,根據pd調度,只對部分region進行遷移,系統開銷理論上小的多.
運維成本
-
DRDS
- 由於DRDS多由雲廠商開發,本質上是一種服務,不存在運維成本,只有溝通成本
- 由於proxy層技術不透明,數據又基於RDS,系統性能優化需要與廠商溝通解決
-
Tidb
- 社區提供了ansible爲基礎的安裝運維包,可以說單純運維門檻不高,基於prometheus和grafana提供比較完善的監控系統
- 性能優化一部分靠生態提供的工具,pd-ctl、tidb-ctl等。另一方面靠社區的相應
- 源碼透明,可以深入瞭解其實現
應用場景
-
DRDS
- 順時高峯且易形成數據熱點的場景
DRDS的分片機制爲HASH分片,天然將數據打散到各個節點,藉助RDS本身的緩存機制可以很好的緩解數據熱點。比如企業的考勤系統或銀行的櫃員系統,在早上上班高峯併發量多,幾分鐘到一個小時的時間內員工會集中打卡或者登錄單例數據庫會瞬間達到性能瓶頸。
- 順時高峯且易形成數據熱點的場景
-
Tidb
-
多租戶SAAS應用:
該場景多爲多租戶場景,SAAS供應商爲每一個用戶提供單獨的庫,每個數據庫的數據量不均衡。如果使用mysql單實例掛載多庫的方式只能縱向擴展;多實例多庫方式要麼在應用層爲每個應用程序配置不同的數據庫url,要麼實現業務數據router;採用tidb可以統一管理數據資源,將多個實例轉化爲一個集羣維護,同時藉助tidb的數據分片機制避免單一用戶形成實例熱點。
-
微服務架構統一管理數據資源:
微服務架構的一個原則是數據可拆分,但如果每個微服務使用mysql主備方式維護一組mysql實例不僅不便於管理,而且由於每個服務對數據庫資源使用的不均衡及易造成資源浪費。應用tidb集羣不僅可以很好的解決上述問題,而且便於維護,同時就業務來講比較容易形成數據服務中間層。
-
備份機制
-
DRDS
依賴於RDS本身的備份機制 -
Tidb
- tidb遵循mysql協議,全量情況下可以通過mydumper等邏輯備份工具備份數據
- 增量數據可以通過社區提供的TiDB-Binlog實時生成增量備份文件
應用改造成本
- DRDS
- 分片鍵的選擇,實際開發中通常會存在說幹業務依賴於同一張表的情況,通過某一個列作爲分片條件提高某項業務性能時可能隱性降低某些業務的性能。
- 分片算法的選,DRDS的拆分算法很多,擇簡單取模、數值向右移、雙拆分列哈希等等,需要開發者先弄清楚這些概念再根據業務情況進行選擇
- 拆分後的表不支持全局唯一約束,如果由於業務需求必須維護全局唯一隻能通過建立中間表的方式維護唯一性,增加開發成本和數據庫調用次數
- 拆分後的表部分sql要根據DRDS的擴展語法重寫
- Tidb
- Tidb的sql實質上是mysql語法的一個完全子集,如果業務沒有用到mysql的內建函數和外鍵約束的話基本可以平滑遷移,只需要對部分sql根據tidb的架構特性進行優化
- 如果重度應用mysql的系統存在某些tidb不支持的函數,那麼這部分功能需要應用端實現
總體上來講,DRDS的應用改造成本主要集中在業務數據拆分上,以及由於數據拆分帶來的業務應用重構;tidb由於自身架構原生支持分片所以不存在數據拆分問題,應用重用主要由於對mysql的私有內建函數依賴重。
個人觀點
DRDS起源於DB中間件,通過hash算法做數據分片用於擴展單機數據庫的不足,屬於過度產品,擴展時數據再平衡的時間會隨着數據及節點數量的增加而增加。從應用改造後續維護的角度來講性價比不高。從場景上來講DRDS的hash分片機制可以更好的散列數據,更加不易形成數據熱點;Tidb在頻發訪問的數據量小於64M時易形成熱點,當數據的範圍大於64M的時候幾乎可以數據會被分配到其他節點熱點也隨之消除。從應用架構來考慮,這個量級的熱數據完全可以通過緩存解決。tidb從架構來講是一個很優雅的數據庫系統,社區及公司歷史不長但發展很快,在實際使用過程中會遇到一些坑,這些坑一部分是由於產品成長過程中的bug或者待優化feature,一部分是由於單機環境和分佈式環境的差異造成的。嘗試新事物,也許未來收益更大。