全球部署的分布式數據庫 YugabyteDB,了解一下?


作者:Eric Fu
鏈接:https://ericfu.me/yugabyte-db-introduction/

Yugabyte DB 是一個全球部署的分布式數據庫,和國內的 TiDB 和國外的 CockroachDB 類似,也是受到 Spanner 論文啟發,所以在很多地方這幾個數據庫存在不少相似之處。

與 Cockroach 類似,Yugabyte 也主打全球分布式的事務數據庫——不僅能把節點部署到全球各地,還能完整支持 ACID 事務,這是他最大的賣點。除此以外還有一些獨特的特性,比如支持文檔數據庫接口。如果我猜的沒錯,Yugabyte 早期被設計成一個文檔數據庫,后來才調整技術路線開始主打 SQL 接口。

本文信息主要來自於 Yugabyte 的官方文檔:

https://docs.yugabyte.com/

以及其 GitHub 主頁:

https://github.com/yugabyte/yugabyte-db

系統架構

邏輯上,Yugabyte 采用兩層架構:查詢層和存儲層。不過這個架構僅僅是邏輯上的,部署結構中,這兩層都位於 TServer 進程中。這一點和 TiDB 不同。

Yugabyte 的查詢層支持同時 SQL 和 CQL 兩種 API,其中 CQL 是兼容 Cassandra 的一種方言語法,對應於文檔數據庫的存儲模型;而 SQL API 是直接基於 PostgresQL 魔改的,能比較好地兼容 PG 語法,據官方說這樣可以更方便地跟隨 PG 新特性,有沒有官方說的這么美好我們就不得而知了。

Yugabyte 的存儲層才是重頭戲。其中 TServer 負責存儲 tablet,每個 tablet 對應一個 Raft Group,分布在三個不同的節點上,以此保證高可用性。Master 負責元數據管理,除了 tablet 的位置信息,還包括表結構等信息。Master 本身也依靠 Raft 實現高可用。

基於 Tablet 的分布式存儲

這一部分是 HBase/Spanner 精髓部分,Cockroach/TiDB 的做法幾乎也是一模一樣的。如下圖所示,每張表被分成很多個 tablet,tablet 是數據分布的最小單元,通過在節點間搬運 tablet 以及 tablet 的分裂與合並,就可以實現幾乎無上限的 scale out。每個 tablet 有多個副本,形成一個 Raft Group,通過 Raft 協議保證數據的高可用和持久性,Group Leader 負責處理所有的寫入負載,其他 Follower 作為備份。

下圖是一個例子:一張表被分成 16 個 tablet,tablet 的副本和 Raft Group leader 均勻分布在各個節點上,分別保證了數據的均衡和負載的均衡。

和其他產品一樣,Master 節點會負責協調 tablet 的搬運、分裂等操作,保證集群的負載均衡。這些操作是直接基於 Raft Group 實現的。這里就不再展開了。

有趣的是,Yugabyte 采用哈希和范圍結合的分區方式:可以只有哈希分區、也可以只有范圍分區、也可以先按哈希再按范圍分區。之所以這么設計,猜測也是因為 Cassandra 的影響。相比之下,TiDB 和 Cockroach 都只支持范圍分區。

哈希分區的方式是將 key 哈希映射到 2 字節的空間中(即 0x00000xFFFF),這個空間又被划分成多個范圍,比如下圖的例子中被划分為 16 個范圍,每個范圍的 key 落在一個 tablet 中。理論上說最多可能有 64K 個 tablet,這對實際使用足夠了。

哈希分區的好處是插入數據(尤其是從尾部 append 數據)時不會出現熱點;壞處是對於小范圍的范圍掃描(例如 pk BETWEEN 1 AND 10)性能會比較吃虧。

基於 RocksDB 的本地存儲

每個 TServer 節點上的本地存儲稱為 DocDB。和 TiDB/Cockroach 一樣,Yugabyte 也用 RocksDB 來做本地存儲。這一層需要將關系型 tuple 以及文檔編碼為 key-value 保存到 RocksDB 中,下圖是對文檔數據的編碼方式,其中有不少是為了兼容 Cassandra 設計的,我們忽略這些,主要關注以下幾個部分:

  • key 中包含
    • 16-bit hash:依靠這個值才能做到哈希分區
    • 主鍵數據(對應圖中 hash/range columns)
    • column ID:因為每個 tuple 有多個列,每個列在這里需要用一個 key-value 來表示
    • hybrid timestamp:用於 MVCC 的時間戳
  • value 中包含
    • column 的值

如果撇開文檔模型,key-value 的設計很像 Cockroach:每個 cell (一行中的一列數據)對應一個 key-value。而 TiDB 是每個 tuple 打包成一個 key-value。個人比較偏好 TiDB 的做法。

分布式事務:2PC & MVCC

和 TiDB/Cockroach 一樣,Yugabyte 也采用了 MVCC 結合 2PC 的事務實現。

時間戳

時間戳是分布式事務的關鍵選型之一。Yugabyte 和 Cockroach 一樣選擇的是 Hybrid Logical Clock (HLC)。

HLC 將時間戳分成物理(高位)和邏輯(低位)兩部分,物理部分對應 UNIX 時間戳,邏輯部分對應 Lamport 時鍾。在同一毫秒以內,物理時鍾不變,而邏輯時鍾就和 Lamport 時鍾一樣處理——每當發生信息交換(RPC)就需要更新時間戳,從而確保操作與操作之間能夠形成一個偏序關系;當下一個毫秒到來時,邏輯時鍾部分歸零。

不難看出,HLC 的正確性其實是由 Logical Clock 來保證的:它相比 Logical Clock 只是在每個毫秒引入了一個額外的增量,顯然這不會破壞 Logical Clock 的正確性。但是,物理部分的存在將原本無意義的時間戳賦予了物理意義,提高了實用性。

個人認為,HLC 是除了 TrueTime 以外最好的時間戳實現了,唯一的缺點是不能提供真正意義上的外部一致性,僅僅能保證相關事務之間的“外部一致性”。另一種方案是引入中心授時節點(TSO),也就是 TiDB 使用的方案。TSO 方案要求所有事務必須從 TSO 獲取時間戳,實現相對簡單,但引入了更多的網絡 RPC,而且 TSO 過於關鍵——短時間的不可用也是極為危險的。

HLC 的實現中有一些很 tricky 的地方,比如文檔中提到的 Safe timestamp assignment for a read request。對於同一事務中的多次 read,問題還要更復雜,有興趣的讀者可以看 Cockroach 團隊的這篇博客 Living Without Atomic Clocks:

https://www.cockroachlabs.com/blog/living-without-atomic-clocks/)。

事務提交

毫不驚奇,Yugabyte 的分布式事務同樣是基於 2PC 的。他的做法接近 Cockroach。事務提交過程中,他會在 DocDB 存儲里面寫入一些臨時的記錄(provisional records),包括以下三種類型:

  • Primary provisional records:還未提交完成的數據,多了一個事務ID,也扮演鎖的角色
  • Transaction metadata:事務狀態所在的 tablet ID。因為事務狀態表很特殊,不是按照 hash key 分片的,所以需要在這里記錄一下它的位置。
  • Reverse Index:所有本事務中的 primary provisional records,便於恢復使用

事務的狀態信息保存在另一個 tablet 上,包括三種可能的狀態:Pending、Committed 或 Aborted。事務從 Pending 狀態開始,終結於 Committed 或 Aborted。

事務狀態就是 Commit Point 的那個“開關”,當事務狀態切換到 Commited 的一瞬間,就意味着事務的成功提交。這是保證整個事務原子性的關鍵。

完整的提交流程如下圖所示:

另外,Yugabyte 文檔中提到它除了 Snapshot Isolation 還支持 Serializable 隔離級別,但是似乎沒有看到他是如何規避 Write Skew 問題的。從 Release Notes 看來這應該是 2.0 GA 中新增加的功能,等更多信息放出后再研究吧!

競品對比

以下表格摘自 Compare YugabyteDB to other databases:

https://docs.yugabyte.com/latest/comparisons/

References

  1. https://www.yugabyte.com/
  2. https://docs.yugabyte.com/
  3. https://www.cockroachlabs.com/blog/living-without-atomic-clocks/

近期熱文推薦:

1.600+ 道 Java面試題及答案整理(2021最新版)

2.終於靠開源項目弄到 IntelliJ IDEA 激活碼了,真香!

3.阿里 Mock 工具正式開源,干掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式發布,全新顛覆性版本!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM