天天看點

NoSQL 資料庫不應該放棄 Consistency

本文發于infoq,

https://www.infoq.cn/article/rhzs0KI2G

*Y2r9PMdeNv 。轉回自己的部落格。

談到 NoSQL,一定會提及一緻性(Consistency),按照 CAP 定理,有些 NoSQL 資料庫放棄了一緻性,但是 NoSQL 放棄是必然的選擇嗎?

從 1970’s,關系型資料庫(RDB,Relational Database)被發明以來,關系型資料庫就是建構應用的通常的選擇。關系型資料庫對使用者提供 ACID 保證,非常友善開發者使用。從 1990’s 開始,NoSQL 系統開始出現。NoSQL 系統是一類對立于關系資料庫的資料庫系統,他們從架構上放棄了傳統的關系型資料庫的的關系模型和 SQL 的接口。

與 NoSQL 系統相伴而來的 2 個詞是 BASE 和 CAP,這 2 個詞對分布式系統有着非常深遠的影響。我相信就是在這 2 個詞的影響下,很多 NoSQL 系統從架構的初始就放棄了一緻性(consistency)選擇了一種最終一緻性(Eventual consistency)和可用性 (Availability)。雖然我非常認同 CAP 和 BASE 這 2 個詞,但是我不認為在 CAP 和 BASE 的作用下,NoSQL 系統選擇放棄一緻性是一個必然的事情。

首先來回顧一下 CAP 和 BASE 這 2 個概念的曆史。這 2 個概念都是由 Eric Brewer 提出的,Brewer 目前是 Google 公司的基礎設施部門(Infrastructure)的副總裁(VP,Vice President)。在 1997 年,在 SOSP(Symposium on Operating Systems Principles) 上,名為的演講 [1] 總結了 Brewer 等人的近期工作,演講中說他們正在工作的叢集服務并沒有采用當時公認的具有 ACID 特性的關系型資料庫作為架構,而是在架構上放棄了關系型資料庫的 ACID 特性。并且為他們的這個架構選擇構造了一個新的詞 BASE,BASE 這個詞的選擇有刻意為之成分,ACID 在英語裡有酸性的意思,而 BASE 有堿性的意思,很明顯 BASE 是與?ACID 對立的。

ACID 和 BASE 分别是如下單詞的首字母縮寫:

ACID:Atomicity, Consistency, Isolation, Durability

BASE: Basically Available, Soft State, Eventual Consistency

BASE 主張放棄掉 ACID,主要是放棄 ACID 中的 Consistency,并且讓系統達到基本可用(Basically Available),柔性狀态(Soft State),最終一緻(Eventual Consistency)。系統建構者可以不僅僅選擇 ACID,BASE 也稱為一種選擇,也就是在 ACID 和 BASE 中選擇其一。本質上來講,就是在 ACID 代表的一緻性 (Consistency) 和 BASE 代表的可用性(Availability)二者之間做出選擇。雖然在 BASE 提出時,還沒有明确說明在一緻性和可用性間做出架構選擇,但是已經為後面 CAP 的提出做好了伏筆。

到 2000 年,Brewer 在 PODC(Principles of Distributed Computing)做了名為 [2] 的演講,演講的主旨是闡明如何建構健壯的分布式系統。在這次演講中,Brewer 近一步分析比較了 ACID 和 BASE,并且抽象了 ACID 和 BASE 的核心特性,也就是 ACID 的一緻性(Consistency),BASE 的可用性(Availability),并且擴充了第 3 個次元,也就是網絡分區(Network Partition),進而提出了CAP 猜想,這個猜想說:

在分布式系統中,最多能同時滿足以下 3 個屬性中的 2 個:

C (Consistency), A (Availability), P (Tolerance to network Partitions)

根據這個猜想,會存在 3 類系統:

放棄 P,系統具有 CA 特性,這類系統諸如單機資料庫

放棄 A,系統具有 CP 特性,這類系統諸如分布式資料庫、分布式鎖

放棄 C,系統具有 AP 特性,這類系統諸如 web caching、DNS

可用性是非常重要的一個特性,特别是在網際網路行業中,服務當機對商業的影響是非常大的,是以依據 CAP 定理放棄一緻性也就是自然的選擇了。特别是在 Amazon 的 CTO Werner Vogels 詳細介紹了 Eventually Consistent[5] 和 Amazon 的 Dynamo 系統的論文 [12] 發表後,大量追求可用性放棄一緻性的 NoSQL 系統出現。

到了 2002 年,GilBert 和 Lynch[3],重新定義了 CAP 這 3 個屬性(重新定義的屬性比 Brewer 猜想中的屬性的範圍小了很多),并且證明了 CAP 這 3 個屬性不能同時達到,進而将 CAP 猜想變成了CAP 定理。

CAP 定理中的 3 個屬性定義如下 [3,6]:

Consistency: 是指原子一緻性(Atomic consistency)或者線性一緻性(linearizable consistency),這是一種非常高的一緻性級别,很少有系統能夠達到。

Availability: 是指完全的可用性,也就是每個到達每個沒有當機的節點上的讀寫請求都能在一個合理的時間傳回一個響應。這裡的關鍵點是每個請求到達每個非當機的節點。這也是一種非常高的可用性水準,也很少有系統能夠達到。

Partition Tolerant: 是指系統能夠在出現網絡分區的情況下,繼續正确響應,即保持系統該有的特性,或者說保持一緻性或者可用性。

Glibert 和 Lynch 重新定義的 CAP 定理非常嚴謹,但是隻證明了 3 個屬性不能同時具有。然而 Brewer 猜想中的 3 個屬性的定義、3 選 2 的描述,3 分的分類法(AP,CP,CA3 種分類)卻不是非常嚴謹,這也是 CAP 出現之後,很多人懷疑和挑戰 CAP 的原因。Brewer 在 2012 年重新寫了一篇文章 [4],也承認最初的 CAP 表述非常令人誤解。事實上,CAP 定理的适用範圍是非常小的。 雖然 CAP 從出生開始就有很多問題,但是它仍然推動了 NoSQL 運動,很多系統架構者依據 CAP 定理,主動放棄了一緻性,但實際上,很多時候這些系統都是不滿足 CAP 定理的适用範圍的。

CAP 的故事到此并未完結,2017 年,Brewer 已經是 Google 公司的基礎設施(Infrastructure)部門的副總裁(VP,Vice President)了,并且這時 Google 公司的第一代 Spanner 系統已經誕生 [9]。Brewer 寫了一篇文章講述了 Google 公司的 Spanner 系統 [7],并且近一步闡述了按照 CAP 定理 Spanner 是一個什麼樣特性的系統。在文中,Brewer 指出 Spanner 系統說是 " 實際上的 CA"(effectively CA)系統。從架構上來講,Spanner 是一個 CP 系統,也就是說當出現網絡分區時,Spanner 選擇的是保證資料的一緻性,放棄可用性的。但實際上,Spanner 是具有非常高可用性效果的一個系統,從架構上 Spanner 沒有達到 CAP 定理要求的那種完全可用性,但是也達到非常高的可用性,由于采用多副本的設計,個别副本出現網絡分區,并不影響使用者能感覺到的可用性。按 CAP 定理的定義,當這些個别副本出現網絡分區時,這些節點是不可用的,也就是系統沒有達到完全可用性。但是此時的使用者請求是可以被其他副本服務的,此時服務是可用的,也就是說使用者仍然感覺到 Spanner 是可用的。是以說使用者感覺的可用性和 CAP 定理中的可用性不是一個概念。我們追求的應該是使用者感覺的可用性。

使用者可感覺的可用性,通常用 SLA 來表示,也就是我們通常說的幾個 9 的可用性。Brewer 在文章中也給出了 Google 關于 Spanner 系統的 SLA 的資料,從資料我們可以看到,由于網絡分區導緻的服務可用的比例是比較小的,有很大一部分導緻服務不可用的原因是諸如軟體 bug、配置錯誤、運維誤操作等導緻的。也就是說,即便在架構上采用了達到 CAP 定理要求的可用性,實際使用者可感受到的服務可用性,也就 SLA 也不會提高多少。這也是我從業這麼多年的一個體會,系統的不穩定更多來自系統開發者的日常失誤,加強代碼品質,加強開發流程規範,加強生産運維規範,更能大大提高系統的可用性。是以,在架構層面,因為可用性放棄一緻性往往是得不償失的。

雲計算的大潮下,不放棄一緻性也是非常明智的。一個托管在雲上的資料存儲服務,如果你放棄了一緻性選擇可用性,使用者是感受不明顯,因為使用者不會對架構設計采用達到的 CAP 定理的可用性而買單,使用者隻會為你的服務達到 SLA 買單。然而資料存儲服務是否具有一緻性,使用者是能夠非常明顯的感受到的。Amazon 公司的内部的 Dynamo[12] 在架構上是可以達到 CAP 定理中的可用性要求的,但是 Amazon 在 AWS 雲上售賣的 DynamoDB 并不是采用的這一架構,也許就是出于這個原因 [10]。

那麼我們選擇一緻性得到的好處是什麼那?很多時候,說到一緻性時,都會拿金融和錢相關的例子來說明一緻性的必要性,但是我相信金融行業并不強依賴一緻性 [10]。我認為一緻性給我帶來的是開發的友善性。Brewer 雖然提出了 BASE 概念,但是他并沒有詳細闡述這個概念。2008 年 EBay 公司的 Dan Pritchett,寫了一遍文章 [8],通過舉例詳細闡述了在放棄了 ACID 以後,如何采用 BASE 架構實作相同的需求,向我們推薦了 BASE 這種架構模式。通過這篇文章,我們我可以看到如果放棄了 ACID 而選擇 BASE 的話,本來一個非常簡單的功能,需要加入消息隊列等手段才能讓系統達到最終一緻性,應用的整體架構複雜了很多。

類似于 Pritchett 文章中說明的一樣,使用不具有一緻性的 NoSQL 系統,你需要仔細甄别你的使用場景,判斷你的使用場景是否可以讓你放棄一緻性。即便你要使用 BASE 架構,也不是簡單地采用一個具有最終一緻性的 NoSQL 系統,替換掉 ACID 資料庫就好了,你需要設計好各種手段,處理掉具有最終一緻性的 NoSQL 系統帶來的異常,讓你的整個應用達到柔性狀态和最終一緻。BASE 中所說的最終一緻和很多 NoSQL 系統所具有的最終一緻有些細微的差别。這個差别簡單來說是,BASE 中所說的最終一緻是保證系統狀态是正确的;而很多 NoSQL 系統最終一緻隻保證最終一緻,但是不保證這個狀态是你想要的正确的狀态 [11]。

最後,個人的一個觀點是,如果一個 NoSQL 系統做為緩存使用,為了追求低延時,可以放棄一緻性,大資料和離線計算的場景類似于這種場景,很多 NoSQL 系統是非常适用的;但是如果 NoSQL 系統作為資料庫來用,那麼這個 NoSQL 系統最好不要因為可用性放棄一緻性,同時通過多副本技術和良好運維達到實際的高可用性,即達到實際上的 CA(effectively CA),這樣可以大大降低使用者的使用負擔。

由于篇幅所限,本文中關于一緻性、CAP、BASE、ACID 的很多技術細節的闡述未能詳盡,拟另行成文讨論。成文倉促,有錯漏之處歡迎各位大神指正。

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

1.Cluster-Based Scalable Network Services, A. Fox et al., 1997.

2.Towards Robust Distributed Systems, E. Brewer, 2000.

3.Brewer’s conjecture and the feasibility of consistent, available, partition-tolerant web services, Seth Gilbert, Nancy Lynch, 2002

4.CAP twelve years later: How the “rules” have changed, Eric Brewer, 2012

5.Eventually Consistent - Revisited, Werner Vogels, 2008

6.Understanding the CAP Theorem, Akhil Mehra,

https://dzone.com/articles/understanding-the-cap-theorem

7.Spanner, TrueTime & The CAP Theorem, Eric Brewer, 2017,

https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/45855.pdf

8.Base: An Acid Alternative,Dan Pritchett,

https://queue.acm.org/detail.cfm?id=1394128

9.Spanner: Google’s Globally-Distributed Database,2012

10.Designing Data-Intensive Applications, Martin Kleppmann

11.Jepsen: Cassandra,Kyle Kingsbury,

https://aphyr.com/posts/294-jepsen-cassandra

12.Dynamo: Amazon’s Highly Available Key-value Store, Giuseppe DeCandia et al., 2007

繼續閱讀