NoSQL 与 CAP 理论
之前我們討論了傳統(tǒng)的數(shù)據(jù)庫事務(wù)的 ACID 特性:?解讀事務(wù)的ACID!?其實傳統(tǒng)數(shù)據(jù)庫和 NoSQL 中對于可用性、一致性的理解不一樣。 因為有時候會聽到一些新型數(shù)據(jù)庫宣稱滿足強一致、高可用、且多地多中心容忍網(wǎng)絡(luò)分區(qū),但是 CAP 不是說不能三者同時滿足嗎?這些矛盾來源于對 CAP 理解有偏差。今天來討論一下 NoSQL 的 CAP 理論。
本文預(yù)計閱讀時間 7 分鐘。
NoSQL數(shù)據(jù)庫
一種新技術(shù)的出現(xiàn)是需求推動的,那么對數(shù)據(jù)庫的什么需求推動了 NoSQL 的出現(xiàn)呢?看看傳統(tǒng)數(shù)據(jù)庫在使用時的一些問題:
(1)大數(shù)據(jù)量情況下吞吐率達不到要求,有單點瓶頸。
(2)事務(wù)的ACID特性要求太高,很多應(yīng)用場景不需要這個約束。
(3)具有單點故障,機器宕機后就沒法用了,雖然可以做主從,但是還需要人為干預(yù),有一段時間不可用。
(4)單節(jié)點存不下全部數(shù)據(jù)。
(5)數(shù)據(jù)容易丟失,不做主備的話數(shù)據(jù)只有一份,磁盤壞掉數(shù)據(jù)就丟了。
因此,傳統(tǒng)數(shù)據(jù)庫一般應(yīng)用于銀行系統(tǒng)、醫(yī)療系統(tǒng)這些對操作的要求比較高或者數(shù)據(jù)量不大的場景。而一些需要高可用性的應(yīng)用,如Facebook、淘寶、亞馬遜等,傳統(tǒng)數(shù)據(jù)庫就無法滿足要求。
于是,人們希望拋棄傳統(tǒng)數(shù)據(jù)庫的思想,構(gòu)建分布式 NoSQL 數(shù)據(jù)庫,這種數(shù)據(jù)庫有下面幾個目標(biāo):
(1)每個節(jié)點都可以提供讀寫服務(wù),提高系統(tǒng)吞吐率,可動態(tài)增刪節(jié)點,集群的吞吐率隨著節(jié)點的增加而線性增長。
(2)去掉了事務(wù),只提供比較簡單的讀寫接口。
(3)避免單點故障,由多個節(jié)點組成的集群,一個節(jié)點壞了其他節(jié)點還能提供服務(wù)。
(4)所有節(jié)點的磁盤都可以用來存儲數(shù)據(jù),提供分布式存儲能力。
(5)為保證數(shù)據(jù)不丟失,采用副本機制,一個數(shù)據(jù)存多份,分別放在不同節(jié)點。
(6)為了控制數(shù)據(jù)的存儲位置,還提出了數(shù)據(jù)分區(qū)的概念。
CAP理論
1998年 UC Berkeley 的 Eric Brewer 提出了 CAP 理論,1999年一篇論文進行了總結(jié)
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.67.6951&rep=rep1&type=pdf
在構(gòu)建 NoSQL 數(shù)據(jù)庫時,往往需要在很多方面做平衡。Brewer 在2000年左右提出了 CAP 理論, Consistency、Availability、Partition Tolerance 的首字母縮寫。
CAP理論:一個分布式系統(tǒng)不可能同時滿足一致性、可用性和分區(qū)容錯性,最多只能同時滿足其中的兩個。
這個分布式系統(tǒng)一般是指在異步網(wǎng)絡(luò)中的,異步網(wǎng)絡(luò)中沒有全局時鐘,節(jié)點只能根據(jù)接收到的消息和本地計算做決策。
有的對 CAP 的誤解也來源于對這三個性質(zhì)的具體含義不清,下面我們先看看這三個性質(zhì)分別指什么。
一致性
CAP 的一致性與傳統(tǒng)關(guān)系數(shù)據(jù)庫中 ACID 的 C 不一樣。ACID 中的 C 關(guān)心的是數(shù)據(jù)庫中的約束,有對單個數(shù)據(jù)值的約束,也有對多個數(shù)據(jù)之間值的約束。而CAP 的一致性關(guān)心的是一個數(shù)據(jù)項不同副本的值是否相同。
在 NoSQL 數(shù)據(jù)庫中,由于數(shù)據(jù)有多個副本,一個寫操作需要更新所有副本,由于存在節(jié)點間通訊的延遲,可能有的節(jié)點的副本被更新了,有的還是舊值,這時讀取不同的副本返回的值就會不一致。因此,CAP 中的一致性指的是副本一致性,或者相互一致性(mutual Consistency),他們和一個瞬時狀態(tài)有關(guān),這個狀態(tài)叫相互一致:
相互一致:如果系統(tǒng)中每個數(shù)據(jù)項的所有副本的值都相同,那么系統(tǒng)處于相互一致的狀態(tài)。在某一時刻,這個狀態(tài)只有滿足或不滿足兩種情況。
我們可以認(rèn)為 NoSQL 數(shù)據(jù)庫僅提供簡單的對單個數(shù)據(jù)項的讀寫操作,如 write(a),read(b),write(b)等,在這種情況下,一致性的表現(xiàn)就和不同節(jié)點間讀寫操作的順序有關(guān)了。因此,很多一致性級別在規(guī)定讀寫操作的順序和結(jié)果。
CAP中的一致性指的是強一致性:當(dāng)更新事務(wù)提交時,所有副本處于相互一致的狀態(tài)。
從操作的角度看:所有操作必須存在一個全局唯一順序,使每個操作看起來好像是在一個瞬間完成的。在這種情況下,在一個寫操作之后的讀操作可以讀到這個寫的值。
所有節(jié)點都可以讀到已經(jīng)更新的結(jié)果,看起來就像是一個單機數(shù)據(jù)庫,而且操作是串行的,和ACID隔離性中的可串行化隔離級別一樣。
可用性
CAP 中的可用性指的是系統(tǒng)每個節(jié)點都能處理請求(接收請求并返回結(jié)果)。
而一般傳統(tǒng)數(shù)據(jù)庫的可用性是指系統(tǒng)做為一個整體能否對外提供服務(wù),只要有一個節(jié)點或多數(shù)節(jié)點能提供響應(yīng)就可以稱為可用。
分區(qū)容忍性
分區(qū)就是網(wǎng)絡(luò)分區(qū),即一個集群被分割成了多個分區(qū),每個分區(qū)內(nèi)部的節(jié)點可以通信,而無法跨分區(qū)交流,而且這個分區(qū)要假設(shè)是可能永久存在的。網(wǎng)路分區(qū)是分布式系統(tǒng)中逃不掉的。
而分區(qū)容忍性則是說在出現(xiàn)網(wǎng)絡(luò)分區(qū)時,系統(tǒng)能否正常對外提供服務(wù)。
舉例
這張圖是CAP里比較經(jīng)典的圖了。由于沒有NoSQL同時滿足三個,因此只能二選一。
傳統(tǒng)數(shù)據(jù)庫由于只有一個節(jié)點,沒有網(wǎng)絡(luò)分區(qū)問題,正常情況下可以實現(xiàn)強一致性和可用性。而傳統(tǒng)數(shù)據(jù)庫的主備技術(shù)則是犧牲了可用性來保證一致性。
由于 NoSQL 數(shù)據(jù)庫中網(wǎng)絡(luò)分區(qū)是不可避免的,當(dāng)出現(xiàn)網(wǎng)絡(luò)分區(qū)時,如下圖左圖,當(dāng)接收到一個寫操作 A=2(這個寫請求只會被發(fā)送到一個節(jié)點上),我們假設(shè)每個節(jié)點執(zhí)行操作需要得到另外兩個節(jié)點的認(rèn)可才能執(zhí)行并返回結(jié)果。這時只能在一致性和可用性里二選一。
如果保證一致性,那么任何接收到請求的節(jié)點都無法收到全部節(jié)點的認(rèn)同,所以這個操作會被懸掛,最終返回超時或執(zhí)行錯誤。
如果保證可用性,可能有一個網(wǎng)絡(luò)分區(qū)接收到這個寫請求,并在當(dāng)前分區(qū)內(nèi)同步寫請求,這是就會與另一個分區(qū)數(shù)據(jù)不一致。這個分區(qū)是隨機的,可能是上圖所示的 N3,也可能是 N1 和 N2。
總結(jié)
有人詬病 CAP 理論,認(rèn)為 CAP 中的 P 是廢話,或者 CAP 太簡單了,沒有量化,對實際系統(tǒng)的構(gòu)建沒有具體的指導(dǎo)意義。比如我要犧牲一致性,犧牲到什么程度?一致性也有很多種級別,強一致性、因果一致性、最終一致性等。這個在 CAP 中是沒有說的。這確實是 CAP 理論的局限,但是 CAP 理論讓人們在構(gòu)建系統(tǒng)時,聚焦于這三個性質(zhì),并從這三個方面來進行權(quán)衡。
總結(jié)
以上是生活随笔為你收集整理的NoSQL 与 CAP 理论的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: go 商品秒杀系统架构设计
- 下一篇: C++实现生产者消费者