全球部署的分布式數(shù)據(jù)庫 YugabyteDB,了解一下?
點擊關(guān)注公眾號,Java干貨及時送達(dá)
作者:Eric Fu
鏈接:https://ericfu.me/yugabyte-db-introduction/
Yugabyte DB 是一個全球部署的分布式數(shù)據(jù)庫,和國內(nèi)的 TiDB 和國外的 CockroachDB 類似,也是受到 Spanner 論文啟發(fā),所以在很多地方這幾個數(shù)據(jù)庫存在不少相似之處。
與 Cockroach 類似,Yugabyte 也主打全球分布式的事務(wù)數(shù)據(jù)庫——不僅能把節(jié)點部署到全球各地,還能完整支持 ACID 事務(wù),這是他最大的賣點。除此以外還有一些獨特的特性,比如支持文檔數(shù)據(jù)庫接口。如果我猜的沒錯,Yugabyte 早期被設(shè)計成一個文檔數(shù)據(jù)庫,后來才調(diào)整技術(shù)路線開始主打 SQL 接口。
本文信息主要來自于 Yugabyte 的官方文檔:
https://docs.yugabyte.com/
以及其 GitHub 主頁:
https://github.com/yugabyte/yugabyte-db
系統(tǒng)架構(gòu)
邏輯上,Yugabyte 采用兩層架構(gòu):查詢層和存儲層。不過這個架構(gòu)僅僅是邏輯上的,部署結(jié)構(gòu)中,這兩層都位于 TServer 進(jìn)程中。這一點和 TiDB 不同。
Yugabyte 的查詢層支持同時 SQL 和 CQL 兩種 API,其中 CQL 是兼容 Cassandra 的一種方言語法,對應(yīng)于文檔數(shù)據(jù)庫的存儲模型;而 SQL API 是直接基于 PostgresQL 魔改的,能比較好地兼容 PG 語法,據(jù)官方說這樣可以更方便地跟隨 PG 新特性,有沒有官方說的這么美好我們就不得而知了。
Yugabyte 的存儲層才是重頭戲。其中 TServer 負(fù)責(zé)存儲 tablet,每個 tablet 對應(yīng)一個 Raft Group,分布在三個不同的節(jié)點上,以此保證高可用性。Master 負(fù)責(zé)元數(shù)據(jù)管理,除了 tablet 的位置信息,還包括表結(jié)構(gòu)等信息。Master 本身也依靠 Raft 實現(xiàn)高可用。

基于 Tablet 的分布式存儲
下圖是一個例子:一張表被分成 16 個 tablet,tablet 的副本和 Raft Group leader 均勻分布在各個節(jié)點上,分別保證了數(shù)據(jù)的均衡和負(fù)載的均衡。

和其他產(chǎn)品一樣,Master 節(jié)點會負(fù)責(zé)協(xié)調(diào) tablet 的搬運、分裂等操作,保證集群的負(fù)載均衡。這些操作是直接基于 Raft Group 實現(xiàn)的。這里就不再展開了。
有趣的是,Yugabyte 采用哈希和范圍結(jié)合的分區(qū)方式:可以只有哈希分區(qū)、也可以只有范圍分區(qū)、也可以先按哈希再按范圍分區(qū)。之所以這么設(shè)計,猜測也是因為 Cassandra 的影響。相比之下,TiDB 和 Cockroach 都只支持范圍分區(qū)。
哈希分區(qū)的方式是將 key 哈希映射到 2 字節(jié)的空間中(即 0x0000 到 0xFFFF),這個空間又被劃分成多個范圍,比如下圖的例子中被劃分為 16 個范圍,每個范圍的 key 落在一個 tablet 中。理論上說最多可能有 64K 個 tablet,這對實際使用足夠了。

哈希分區(qū)的好處是插入數(shù)據(jù)(尤其是從尾部 append 數(shù)據(jù))時不會出現(xiàn)熱點;壞處是對于小范圍的范圍掃描(例如 pk BETWEEN 1 AND 10)性能會比較吃虧。
基于 RocksDB 的本地存儲
每個 TServer 節(jié)點上的本地存儲稱為 DocDB。和 TiDB/Cockroach 一樣,Yugabyte 也用 RocksDB 來做本地存儲。這一層需要將關(guān)系型 tuple 以及文檔編碼為 key-value 保存到 RocksDB 中,下圖是對文檔數(shù)據(jù)的編碼方式,其中有不少是為了兼容 Cassandra 設(shè)計的,我們忽略這些,主要關(guān)注以下幾個部分:
key 中包含 16-bit hash:依靠這個值才能做到哈希分區(qū) 主鍵數(shù)據(jù)(對應(yīng)圖中 hash/range columns) column ID:因為每個 tuple 有多個列,每個列在這里需要用一個 key-value 來表示 hybrid timestamp:用于 MVCC 的時間戳 value 中包含 column 的值

如果撇開文檔模型,key-value 的設(shè)計很像 Cockroach:每個 cell (一行中的一列數(shù)據(jù))對應(yīng)一個 key-value。而 TiDB 是每個 tuple 打包成一個 key-value。個人比較偏好 TiDB 的做法。
分布式事務(wù):2PC & MVCC
和 TiDB/Cockroach 一樣,Yugabyte 也采用了 MVCC 結(jié)合 2PC 的事務(wù)實現(xiàn)。
時間戳
時間戳是分布式事務(wù)的關(guān)鍵選型之一。Yugabyte 和 Cockroach 一樣選擇的是 Hybrid Logical Clock (HLC)。
HLC 將時間戳分成物理(高位)和邏輯(低位)兩部分,物理部分對應(yīng) UNIX 時間戳,邏輯部分對應(yīng) Lamport 時鐘。在同一毫秒以內(nèi),物理時鐘不變,而邏輯時鐘就和 Lamport 時鐘一樣處理——每當(dāng)發(fā)生信息交換(RPC)就需要更新時間戳,從而確保操作與操作之間能夠形成一個偏序關(guān)系;當(dāng)下一個毫秒到來時,邏輯時鐘部分歸零。
不難看出,HLC 的正確性其實是由 Logical Clock 來保證的:它相比 Logical Clock 只是在每個毫秒引入了一個額外的增量,顯然這不會破壞 Logical Clock 的正確性。但是,物理部分的存在將原本無意義的時間戳賦予了物理意義,提高了實用性。
個人認(rèn)為,HLC 是除了 TrueTime 以外最好的時間戳實現(xiàn)了,唯一的缺點是不能提供真正意義上的外部一致性,僅僅能保證相關(guān)事務(wù)之間的“外部一致性”。另一種方案是引入中心授時節(jié)點(TSO),也就是 TiDB 使用的方案。TSO 方案要求所有事務(wù)必須從 TSO 獲取時間戳,實現(xiàn)相對簡單,但引入了更多的網(wǎng)絡(luò) RPC,而且 TSO 過于關(guān)鍵——短時間的不可用也是極為危險的。
HLC 的實現(xiàn)中有一些很 tricky 的地方,比如文檔中提到的 Safe timestamp assignment for a read request。對于同一事務(wù)中的多次 read,問題還要更復(fù)雜,有興趣的讀者可以看 Cockroach 團(tuán)隊的這篇博客 Living Without Atomic Clocks:
https://www.cockroachlabs.com/blog/living-without-atomic-clocks/)。
事務(wù)提交
毫不驚奇,Yugabyte 的分布式事務(wù)同樣是基于 2PC 的。他的做法接近 Cockroach。事務(wù)提交過程中,他會在 DocDB 存儲里面寫入一些臨時的記錄(provisional records),包括以下三種類型:
Primary provisional records:還未提交完成的數(shù)據(jù),多了一個事務(wù)ID,也扮演鎖的角色 Transaction metadata:事務(wù)狀態(tài)所在的 tablet ID。因為事務(wù)狀態(tài)表很特殊,不是按照 hash key 分片的,所以需要在這里記錄一下它的位置。 Reverse Index:所有本事務(wù)中的 primary provisional records,便于恢復(fù)使用

事務(wù)的狀態(tài)信息保存在另一個 tablet 上,包括三種可能的狀態(tài):Pending、Committed 或 Aborted。事務(wù)從 Pending 狀態(tài)開始,終結(jié)于 Committed 或 Aborted。
事務(wù)狀態(tài)就是 Commit Point 的那個“開關(guān)”,當(dāng)事務(wù)狀態(tài)切換到 Commited 的一瞬間,就意味著事務(wù)的成功提交。這是保證整個事務(wù)原子性的關(guān)鍵。
完整的提交流程如下圖所示:

另外,Yugabyte 文檔中提到它除了 Snapshot Isolation 還支持 Serializable 隔離級別,但是似乎沒有看到他是如何規(guī)避 Write Skew 問題的。從 Release Notes 看來這應(yīng)該是 2.0 GA 中新增加的功能,等更多信息放出后再研究吧!
競品對比
以下表格摘自 Compare YugabyteDB to other databases:
https://docs.yugabyte.com/latest/comparisons/

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






關(guān)注Java技術(shù)??锤喔韶?/strong>


