作者介紹

陳東明,餓了麼北京技術中心架構組負責人,負責餓了麼的產品線架構設計以及餓了麼基礎架構研發工作。曾任百度架構師,負責百度即時通訊產品的架構設計。具有豐富的大規模系統構 建和基礎架構的研發經驗,善於複雜業務需求下的大並發、分散式系統設計和持續優化。個人微信公眾號 dongming_cdm。

Tedisgithub.com/eleme/tedis是基於開源 TiKV 的兼容 Redis 協議的強一致性的 NoSQL 資料庫開源項目。本文介紹一下 Tedis 開源項目的架構設計和特性,以及架構背後的一些思考(包括為何選擇 TiKV 和 Redis 協議)。

先來討論為什麼基於 TiKV 構建我們自己的 NoSQL 資料庫。

首先簡述一下 TiKV[1],TiKV 是 TiDB 的一個子項目,TiDB 是一個分散式的關係型資料庫 [2],TiKV 是 TiDB 的存儲層。TiKV 本身是可獨立於 TiDB 的單獨項目。它是一個強一致、可水平擴展的、高可用的分散式 Key-Value 存儲系統。

選擇 TiKV 的第一個原因是 TiKV 是一個強一致的系統。在我的另外一篇文章中(發表在 InfoQ, 參看 infoq.cn/article/rhzs0K),我闡述了一個觀點:NoSQL 資料庫應該具有一致性,並且通過多副本技術達到實際的高可用,也就是說 NoSQL 資料庫應該是一個「實際上的 CA」 (effectively CA)系統。但是在這篇文章中我並沒有明確說明 NoSQL 該具有的一致性是哪種一致性。實際上,我所說的一致性其實就是一種強一致性 [3],或者更準確的說是線性一致性 [4]。TiKV 正是具有這種線性一致性。TiKV 中的每個數據都會保存 3 個副本,在只有一個副本的節點宕機或者出現網路分區的情況下,另外 2 個副本仍然能夠對外提供服務。理論上來講,同時出現 2 個以上副本同時壞掉的可能性很小,也就是理論上可以達到非常高的可用性。通過 TiKV 滾動升級等運維輔助,如果在實際的生產中,有良好的運維,可以達到實際上非常高的可用性。也就是稱為一個「實際上的 CA」(effectively CA)系統。

TiKV 通過 Raft [5] 協議實現了線性一致性和高可用 2 個特性。Raft 是一種分散式共識協議,通過 Raft 協議,數據可以被認為是原子的寫入到 3 個副本上。共識協議的一個特點就是要寫入大多數,才會認為寫入成功,3 個副本的大多數就是 2 個,也就是在只有一個副本宕機或者網路分區的情況下,仍然可以成功寫入,並且提供讀服務。

選擇 TiKV 的第二個原因是 TiKV 的架構可擴展和生態。在 TiDB 中 TiKV 是獨立的一層,形成了一個很好的可擴展架構,實際上可以在 TiKV 上擴展出很多不同的資料庫出來。TiDB 層本身就是這種架構上的一個擴展。這種架構類似於 Google 公司的第一代的 Spanner 系統 [6],Spanner 系統本身也是一個強一致性的、高可用的分散式 Key-Value 系統。在 Spanner 的基礎之上,Google 構建了 F1 系統 [7],實現了 SQL 協議。2017 年,Google 升級了 Spanner 到第二代 [8],讓 Spanner 本身就具有了 SQL 能力。雖然一代 Spanner+F1 是這樣的架構,但它仍然是一種非常優秀的架構。我們的 Tedis 項目,也是構建在這一可擴展架構上的一個項目,依託於 TiKV 提供的底層能力,向上構建了不同於 SQL 協議的 Redis 協議。我相信 TiKV 的這種可擴展架構,未來可以成為一種生態,還可以在上面「?出」其他的類型的資料庫,比如說 Mango 協議、圖協議。這些資料庫都具有與底層 TiKV 相同的線性一致性和高可用性,區別只在於對外的介面協議不同。目前這種生態已初?端倪,Titan 這個開源項目,與我們的 Tedis 項目非常類似,他們的開源步伐先於我們,目前做的也非常不錯。我相信,我們肯定不是這個生態中的最後一個。

總之基於 TiKV,Tedis 實現了以下的技術特性:

1. 大數據量,可以存儲至少數十 TB 級別的數據。

2. 高性能,在滿足高 QPS 的同時,保證比較低的延時。

3. 高可靠,數據被可靠的持久化存儲,少量機器的損壞不會導致數據的丟失。

4. 高可用,作為在線服務的底層依賴存儲,要有非常完善的高可用性能力,外賣服務不同於電子商務,對實時性要求非常高,對系統的可用性的要求則是更高的。

5. 易運維,可以在不停服的基礎上進行數據遷移和集羣擴容。

接下來,我們討論第二個問題,為什麼選擇 Redis 協議。

SQL 語言與其背後的關係模型,從 1970s 發明以來,一直在應用開發領域佔據這統治地位,雖然在 CAP 定理的推動下 [4],在 NoSQL 運動中,出現很多 NoSQL 系統,就如我前面闡述的一樣,一致性不應該是 NoSQL 出現的理由,去 SQL 和關係模型纔是 NoSQL 出現的動力。但我並不認為 NoSQL 會代替 SQL。雖然 NoSQL 出現的時候,原本表達的意思是「NO SQL(沒有 SQL),但是我覺得另外一種對 NoSQL 的解釋更合適,也就是「Not Only SQL(不僅僅有 SQL)。NoSQL 不是 SQL 的替代品,應該是 SQL 的有力補充。在 NoSQL 運動中,湧現出來的非常優秀的 NoSQL 系統大多都有自己的獨有的介面協議,比如 Redis、MongoDB、Cassandra、圖資料庫等等。他們都有各自非常適用的使用場景,比如 MongoDB 貼近面向對象,圖資料庫適合節點的圖關係運算。而 Redis 貼近開發者數據結構思維,相信每個開發者都是從數組、hash 表、隊列這樣的數據結構中成?起來的。

另外,Redis 本身是一個非常優秀的產品,它的普及程度非常高,特別是在互聯網行業。在每個互聯網公司,Redis 都已經成為工程師開發工具箱中,必備的工具之一。Redis 已經是開發者除 SQL 之外,第二熟悉的產品了。

但是,選擇 Redis 協議,也給我帶來一些實際的困擾,我們有些使用者最初接觸 Tedis 時,總是拿我們和 Redis 相比。但是,雖然我們採用的是 Redis 介面,但是 Tedis 本身並不對標 Redis 這個產品。Redis 是非常優秀的緩存。雖然 Redis 也可以開啟持久化功能,由於 Redis 本身架構設計,開啟持久化的 Redis 仍然不能達到「實際上的 CA」(effectively CA),和 100% 的持久性(durability)。這是 Redis 和 Tedis 的一個很大的區別,Tedis 是一個資料庫,不是一個緩存。

討論完上面的 2 個架構思考,我們來看一下 Tedis 的架構設計。

在 Tedis 中,我們封裝了一個 TiKV 的 SDK,對 Redis 的協議進行了解析,並且將 Redis 協議轉成對 TiKV 的調用。

目前 Tedis 仍然有很多要完善的地方,但是我們會儘快完善如下的事項,在我們的開源日程表中:

1. Redis 命令的補全

2. 壓縮和限流等一些擴展功能

3. Cassandra 協議的支持

寫在最後

作為存儲系統,不應該讓使用者在一致性、可用性這些技術特性上做過多的選擇,使用者應該更多的考慮哪種介面更適合自己的應用場景,自己更熟練使用哪種介面,能用哪種介面更快的進行功能開發。

由於篇幅所限,本文中關於強一致性、線性一致性、Redis、Raft、Spanner 的很多技術細節的闡述未能詳盡,擬另行成文討論。

參考資料:

1. github.com/pingcap/tikv

2. github.com/pingcap/TiDB

3. Eventually Consistent - Revisited,Werner Vogels, 2008, allthingsdistributed.com ually_consistent .html

4. Linearizability: A Correctness Condition for Concurrent Objects,Maurice P. Herlihy and Jeannette M. Wing,1990

5. In Search of an Understandable Consensus Algorithm, Diego Ongaro and John Ousterhout, 2014

6. Spanner: Google』s Globally-Distributed Database, James C. Corbett, Jeffrey Dean et al., 2012

7. F1: A Distributed SQL Database That Scales, Jeff Shute et al., 2013 8.Spanner: Becoming a SQL System, David F. Bacon et al., 2017

Tedis 項目

eleme/tedis?

github.com
圖標

推薦閱讀:
相關文章