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

點擊關注公衆號,Java乾貨及時送達

作者: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/

最後,關注公衆號Java技術棧,在後臺回覆:面試,可以獲取我整理的 Java/ 數據庫系列面試題和答案,非常齊全
參考資料:
  1. https://www.yugabyte.com/
  2. https://docs.yugabyte.com/
  3. https://www.cockroachlabs.com/blog/living-without-atomic-clocks/






關注Java技術棧看更多幹貨



獲取 Spring Boot 實戰筆記!

本文分享自微信公衆號 - Java技術棧(javastack)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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