軟件測試數據庫中NoSQL漫談
NoSQL,意即反SQL運動,是一項全新的數據庫革命性運動,早期就有人提出,發展至2009年趨勢越發高漲。NoSQL的擁護者們提倡運用非關系型的數據存儲,相對于目前鋪天蓋地的關系型數據庫運用,這一概念無疑是一種全新的思維的注入。
什么是NoSQL?wiki上的定義是“NoSQL is a movement promoting a loosely defined class of non-relational data stores that break with a long history of relational databases”。其實并不存在一個叫NoSQL的產品,它是一類non-relational data stores的集合。NoSQL的重點是non-relational,而傳統的數據庫是relational。
我們都知道,傳統關系型數據庫的最大缺陷是擴展性,雖然各個數據庫廠家都有cluster的解決方案,但是不管是share storage還是share nothing的解決方案,擴展性都十分有限。目前解決數據庫擴展性的思路主要有兩個:第一是數據分片(sharding)或者功能分區,雖然說可以很好的解決數據庫擴展性的問題,但是在實際使用過程中,一旦采用數據分片或者功能分區,必然會導致犧牲“關系型”數據庫的最大優勢-join,對業務局限性非常大,而數據庫也退化成為一個簡單的存儲系統。另外一個思路是通過maser-slave復制的方式,通過讀寫分離技術在某種程度上解決擴展性的問題,但這種方案中,由于每個數據庫節點必須保存所有的數據,這樣每個存儲的IO subsystem必然成為擴展的瓶頸,而且masert節點也是一個瓶頸??偟膩碚f,傳統關系型數據庫的擴展能力十分有限。
在說NoSQL之前,首先得說兩個重要的概念,一個是CAP理論,另一個是BASE模型。
CAP
Consistency(一致性),數據一致更新,所有數據變動都是同步的
Availability(可用性),好的響應性能
Partition tolerance(分區容錯性) 可靠性
CAP原理告訴我們,這三個因素最多只能滿足兩個,不可能三者兼顧。對于分布式系統來說,分區容錯是基本要求,所以必然要放棄一致性。對于大型網站來說,分區容錯和可用性的要求更高,所以一般都會選擇適當放棄一致性。對應CAP理論,NoSQL追求的是AP,而傳統數據庫追求的是CA,這也可以解釋為什么傳統數據庫的擴展能力有限的原因。
BASE
Basically Availble:基本可用
Soft-state: 軟狀態/柔性事務
Eventual Consistency:最終一致性
BASE模型是傳統ACID模型的反面,不同與ACID,BASE強調犧牲高一致性,從而獲得可用性?;究捎檬侵竿ㄟ^sharding,允許部分分區失敗。軟狀態是指異步,允許數據在一段時間內的不一致,只要保證最終一致就可以了。最終一致性是整個NoSQL中的一個核心理念,很多NoSQL產品就是基于最終一致性而設計的,包括Amazon的Dynamo.
NoSQL產品簡介
NoSQL是很多non-relational data stores的集合,總體來說,他們基本都是基于Key-value形式的一種分布式存儲,但是每一種NoSQL產品都面向一個特定的應用場景,根據這些應用場景,我們可以把NoSQL分為以下類型(參考了wiki上的定義,只列舉了我們比較熟悉的產品):
KV cache:Memcached
KV store:Tokyo Tyrand/Cab.net,Memcachedb,Berkley DB
Eventually consistent KV store:dynamo,voldemort,Cassandra
Wide columnar store:BigTable,Cassandra,Hbase
document store:MongoDB
KV Cache類型不具有持久化存儲的功能,其中的memcached被我們廣泛使用,用來緩解數據庫的壓力,至于數據持久化存儲的功能則由數據庫來替代了。
KV store具備了持久化存儲的功能,其中的memcachedb是新浪在memcached的基礎上,采用Berkley DB作為存儲層開發的分布式KV store。Tokyo Tyrand/Cabinet是日本最大的SNS社交網站mixi.jp開發的KV store,其中TC是一個NoSQL的數據庫,用來做持久化數據存儲,TT則是TC的網絡接口(兼容memcached協議)。至于Berkley DB則是一個嵌入式數據庫,現在掌握在Oracle手中。
Eventually consistent KV store是以最終一致性原理設計的一類KV store,包括Amazon的Dynamo,Lindedin的voldemort以及Facebook的Cassandra,Dynamo的主要特點是:分布式(去中心化),高可用,可擴展,永遠可寫等等。Dynamo的設計思想是分布式系統中最重要的理論之一,另外一個是Bigtable。
Wide columnar store包括Bigtable,Cassandra和Hbase,這種類型是用來處理結構化數據的,它有幾個特點:具備大規模擴展能力,有類似數據庫中column的概念,非常靈活的schema,采用memtable/sstable的存儲機制,并基于列存儲。Cassandra采用了Dynamo最終一致性的理念,并借鑒了Bigtable的數據模型和實現方式,所以很多人把他看作是開源版本的Bigtable+Dynamo,這種類型的KV store是我們關注的重點。
document store是基于文檔的KV store,這種類型主要面向海量數據處理,其中MongoDB的特點是支持非常復雜的數據類型,而且查詢語言非常強大,有些類似于關系型數據庫。但它并不適合大規模并發讀寫的應用。
下面介紹幾個分布式系統的概念:consistent hashing,virtual node,quorum,vector clock:
consistent hashing
我們通常使用的hash算法是hash() mod n,但是如果發生某個節點失效時,無法快速切換到其他節點。為了解決單點故障的問題,我們為每個節點都增加一個備用節點,當某個節點失效時,就自動切換到備用節點上,類似于數據庫的master和slave。但是依然無法解決增加或刪除節點后,需要做hash重分布的問題,也就是無法動態增刪節點。這時就引入了一致性hash的概念 ,將所有的節點分布到一個hash環上,每個請求都落在這個hash環上的某個位置,只需要按照順時針方向找到的第一個節點,就是自己需要的服務節點。當某個節點發生故障時,只需要在環上找到下一個可用節點即可。一致性hash解決了增刪節點后需要hash重分布的問題,是分布式系統的基礎。
virtual node
虛擬節點是在一致性hash的基礎上,把一臺物理節點虛擬成多個虛擬節點,并映射到hash環的不同位置上。這樣的好處是可以根據機器硬件的性能,靈活的定義虛擬節點的個數。這里所說的虛擬節點不是用虛擬機技術實現的,而是把一個物理節點映射為多個虛擬節點。
quorum NRW
N: 復制的節點數,即一份數據被保存的份數。
R: 成功讀操作的最小節點數,即每次讀取成功需要的份數。
W: 成功寫操作的最小節點數 ,即每次寫成功需要的份數。
這三個因素決定了可用性,一致性和分區容錯性。對于一個分布式系統來說,N通常都大于3,也就說同一份數據需要保存在三個以上不同的節點上,以防止單點故障。W是成功寫操作的最小節點數,這里的寫成功可以理解為“同步”寫,比如N=3,W=1,那么只要寫成功一個節點就可以了,另外的兩份數據是通過異步的方式復制的。R是成功讀操作的最小節點數,讀操作為什么要讀多份數據呢?在分布式系統中,數據在不同的節點上可能存在著不一致的情況,我們可以選擇讀取多個節點上的不同版本,來達到增強一致性的目的。下面我們分析幾個典型的場景:
N=W,R=1,這種情況是最強一致性的,每個節點都被同步寫入,讀取任意節點即可,所以讀取的性能最高,但是可用性是最差的,因為必須保證每個節點都必須成功寫人。
R+W>N,這種情況也是可以保證一致性的,因為讀取數據的節點和同步寫入的節點至少有一個重疊,比如N=3,W=2,R=2,每份數據有三個復本,每次同步寫成功兩份數據,每次讀取至少兩份數據,則說明讀取的數據至少有一份是同步寫人的最新數據,所以一致性可以得到保證,N=3,W=2,R=2是可用性和性能的一個平衡。
N=R,W=1,這種情況最大程度保證了寫的性能,數據只寫一份即成功,而讀取時則需要所有的數據復本,以此來達到保證一致性的目的,但是同樣犧牲了可用性。
W+R<=N,這種情況是不保證一致性的,因為讀取和寫入的節點可能存在不重疊的情況,在數據同步到其他節點的這段時間窗口內,可能會出現數據不一致的情況。
原文轉自:http://www.anti-gravitydesign.com