傳統關係型數據庫面臨的挑戰html
l High Performance——對數據庫高併發讀寫的需求數據庫
l Huge Storage——對海量數據的高效率存儲的需求服務器
l High Scalability & High Availablity——對數據庫的高可擴展性和高可用性的需求。網絡
對於當前的不少網站來講,關係數據庫的不少主要特性每每無用武之地,例如:併發
l 數據庫事務一致性需求異步
不少系統並不要求嚴格的數據庫事務,對讀一致性的要求很低,所以數據庫事務管理成了數據庫高負載下一個沉重的負擔。分佈式
l 數據庫的實時性需求高併發
對關係型數據庫來講,插入一條數據後馬上查詢,是確定能夠讀出來這條數據的,可是對於不少Web應用而言,並不要求這麼高的實時性,比方說我發一條微博以後,過幾秒乃至十幾秒後,別人才提示有新微博,這是徹底能夠的。性能
l 對複雜的SQL查詢,特別是多表關聯查詢的需求大數據
大數據量的Web系統,很是忌諱多個大表的關聯查詢,以及複雜的數據分析類型的SQL報表查詢,特別是SNS類型的網站,從需求以及產品設計角度,就避免這種狀況的產生。每每更多的只是單表的主鍵查詢,以及單表的簡單條件分佈查詢,SQL的功能被極大地弱化了。
什麼是NoSQL
如今通常認爲NoSQL全稱是Not Only SQL,是一種不一樣於關係型數據庫的數據庫管理系統設計方式。對NoSQL最廣泛的解釋是「非關係型的」,強調Key-Value Stores和文檔數據庫的優勢,而不是單純的反對RDBMS。
NoSQL的理論基礎
CAP,BASE和最終一致性是NoSQL數據庫存在的三大基石。
ACID vs. BASE
ACID,指數據庫事務正確執行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。
(這張PPT是Brewer教授在PODC大會上用的PPT。)
BASE內容:
l Basically Availble ——基本可用
l Soft-state ——軟狀態/柔性事務,狀態能夠有一段時間不一樣步
l Eventual Consistency ——最終一致性
CAP原理
分佈式系統中,有三種重要的屬性,分別是:
l 一致性(Consistency):任何一個讀操做老是能讀取到以前完成的寫操做結果,也就是在分佈式環境中,多點的數據是一致的。
l 可用性(Availability):每個操做老是可以在肯定的時間內返回,也就是系統隨時都是可用的。
l 分區容忍性(Tolerance of network Partition):在出現網絡分區(好比斷網)的狀況下,分離的系統也能正常運行。
CAP原理的意思是,一個分佈式系統不能同時知足一致性,可用性和分區容錯性這三個需求,最多隻能同時知足兩個。
注意: 可用性與分區容忍性在一些狀況下很容易混淆。舉個例子,假設系統中有若干個節點宕機了,系統仍然能正常運行,那麼應該說是系統的可用性高仍是分區容忍性高 呢?我的的理解是,這種應該理解爲系統的分區容忍性高。由於若干個節點宕機,能夠理解爲這幾個節點與其它正常的節點失去聯繫了,也就是出現了網絡分區,按 照定義,這屬於分區容忍性的範疇。那麼可用性是什麼?我的的理解可用性更多強調的是,系統對於讀寫操做的反應快慢,反應越快,可用性越高。
CAP原理是由美國著名科學家,Berkerly大學Brewer教授提出的。後來麻省理工學院的兩位科學家證實了CAP原理的正確性。雖然在後來近十年的時間不少人對CAP原理出了不少異議,可是在NoSQL的世界中,它仍是很是有參考價值的。
一致性or可用性,魚和熊掌不可得兼
下面是一個犧牲一致性換取可用性的小例子。
假設N1和N2是分佈式環境下的兩個節點,它們有保存了共同的數據V,它們的值都是V0,A和B是兩個分別對數據進行操做的進程。咱們看看這麼一個過程:A向N1節點寫入了新的V值V1,B讀取V的值。
若是一切正常的話,這個過程看起來像是這樣的:
(1) A寫入V的新值V1。
(2) N1向N2發送消息M以更新V值。
(3) B讀取V的新值V2。
可是現實多是這樣子的:
因爲網絡分區,N1發向N2的消息頗有可能沒送達,那麼,B節點將讀取到一個過期的V值,不一致性產生了。而且當把節點的規模不斷擴大的時候,不一致性問題也會更加嚴重。
因此若是咱們但願A B都是高可用的(也就是低延遲),那麼一致性一般就不能獲得很好的保證,咱們必需要容忍必定的不一致性以換取高可用性。
從客戶端角度看一致性
有不少種客戶端一致性模型:
強一致性:讀取到的數據老是最新的。
弱一致性:讀取到的數據不必定是最新的。
最終一致性:屬於弱一致性,不一樣的是,最終一致性的系統會在後臺異步地更新全部的備份,因此最終全部的備份都會是最新的數據。
最終一致性有一些比較重要的變種,例如:
因果一致性:若是進程A更新了某數據,並通知進程B,那麼進程B接下來的讀操做將必定會讀取到最新的數據,寫操做必定能覆蓋以前的數據。而另外一與進程A無關的進程C則服從最終一致性的狀況。
「讀己之所寫」一致性:客戶端能夠當即看到本身所做的更新,但不能當即看到其餘客戶端的更新。
會話一致性:對於客戶端在一同會話做用域中發起的請求,提供「讀己之所寫」一致性。
單調讀一致性:保證時間上的單調性,保證客戶端在將來的請求中,只會讀到比當前更爲新的數據。
從服務器端角度看一致性
咱們利用一個數學模型來分析一下服務器端對於一致性的實現。瞭解完這個部分,對於具體NoSQL數據庫的理解和分析就能事半功倍了。
Quorum NRW 模型
先看下面這個圖,並定義一些變量。
l N:存儲備份的節點數目,能夠理解爲備份的數目。
l W:更新(寫)操做成功以前所必須更新的最少備份數目。假設W=3,表示至少等到3個備份的數據獲得更新時,更新操做纔算完成。
l R:讀操做所須要鏈接的最少備份數目。假設R=3,表示讀取一個數據時,至少要讀取到這個數據的3個備份,而後選其中最新的備份。
調整N、W、R的取值,數據庫系統的性質就會發生改變。
l N越大,同一個數據的備份越多,系統相對也就越不容易丟失數據。
l W越大,系統的一致性會越高,但更新操做也就越慢。
l R越大,系統的一致性會越高,但讀操做也就越慢。
l W+R>N,系統是強一致性的。爲何?舉例來講,假設N=6,W=R=3,當一個更新操做完成的時候,它至少更新了6個備份中的3個備份,那麼當咱們去讀取這個數據的時候,由於R=3,因此咱們至少得讀3個數據,並從中選擇最新的數據,而W+R>N就意味着讀取的3個數據跟更新的3個數據至少有一個是重疊的,因此讀取的3個數據中必定存在最新的數據,於是就能保證系統是強一致性的。
l W+R<=N,系統是弱一致性的。
幾種特殊狀況:
l W = 1,R = N,對寫操做要求高性能高可用。
l R = 1,W = N,對讀操做要求高性能高可用,好比相似cache之類業務。
l W = R = N / 2 + 1 通常應用適用,讀寫性能之間取得平衡。如N=3,W=2,R=2。
不一樣類型的數據庫對CAP的支持
參考資料
《NoSQL數據庫綜述》,做者範凱
《NoSQL的模式》,做者Ricky Ho