Menu

關聯式資料庫 vs. Key-Value 資料庫

 

Tim Morgan@flickr.com

在我還在上學的時候,key-value這個詞更多的還是和hash表聯繫在一起的。而現在,當我看見key-value這個詞,馬上聯想到的就是 BigTable,SimpleDB和雲計算。當下,key-value store(或者叫key-value Database,雲存儲等等)是個非常時髦的詞彙,越來越多的開發人員(特別是互聯網企業)開始關注和嘗試key-value的存儲形式。這年頭如果你還和別人聊關係型數據庫,貌似你都不好意思和人打招呼。

可是,key-value store真的有這麼神奇嗎?畢竟,關係型數據庫已經主導市場三十多年了。


背景

key-value形式的存儲並不是憑空想出來的。在我看來,是兩個問題導致了key-value這種存儲方式的崛起:


1. 大規模的互聯網應用。對於google,ebay這樣的互聯網企業,每時每刻都有無數的用戶在使用它們提供的互聯網服務,這些服務帶來的就是大量的數據吞吐量,在同一時間,會並發的有成千上萬的連接對數據庫進行操作。在這種情況下,單台服務器或者幾台服務器遠遠不能滿足這些數據處理的需求,簡單的升級服務器性能這樣的scale up的方式也不行,所以唯一可以採用的辦法就是scale out了。scale out的方法有很多種,但大致分為兩類:一類仍然採用RDBMS,然後通過對數據庫的垂直和水平切割將整個數據庫部署到一個集群上,這種方法的優點在於可以採用RDBMS這種熟悉的技術,但缺點在於它是針對特定應用的,就是說,由於應用的不同,切割的方法是不一樣的。關於數據庫的垂直和水平切割的具體細節可以查看文獻【2】。
還有一類就是google改採用的方法,拋棄RDBMS,採用key-value形式的存儲,這樣可以極大的增強系統的可擴展性(scalability),如果要處理的數據持續增大,多加機器就可以了。事實上,key-value的存儲就是由於BigTable等相關論文的發表慢慢進入人們的視野的。

2. 雲存儲。如果說上一個問題還有可以替代的解決方案(切割數據庫)的話,那麼對於雲存儲來說,也許key-value的store就是唯一的解決方案了。雲存儲簡單點說就是構建一個大型的存儲平台給別人用,這也就意味著在這上面運行的應用其實是不可控的。如果其中某個客戶的應用隨著用戶的增長而不斷增長時, 雲存儲供應商是沒有辦法通過數據庫的切割來達到scale的,因為這個數據是客戶的,供應商不瞭解這個數據自然就沒法作出切割。在這種情況 下,key-value的store就是唯一的選擇了,因為這種條件下的scalability必須是自動完成的,不能有人工干預。這也是為什麼幾乎所有的現有的雲存儲都是key-value形式的,例如Amazon的smipleDB,底層實現就是key-value,還有google的 GoogleAppEngine,採用的是BigTable的存儲形式。也許唯一可能例外的是MS的解決方案,我在Qcon大會上聽說MS的Azure平台的下一個版本中就會推出基於RDBMS的雲存儲,儘管我本人仍然對此保持懷疑。

可以看出,以上兩個問題強調的都是 scalability。其實,正如文獻【1】中所說,「Today, we are in a slightly different situation. For an increasing number of applications, one of these benefits is becoming more and more critical; and while still considered a niche, it is rapidly becoming mainstream, so much so that for an increasing number of database users this requirement is beginning to eclipse others in importance. That benefit is scalability.」 。正是由於現在出現的很多應用非常強調scalability,才導致了key-value存儲的出現。key-value store作為一種RDBMS的可能的替代方案,犧牲了部分RDBMS的優勢(這點在下文中會慢慢看到),從而確保了系統的可擴展性 (scalability)。

那麼,key-value store和RDBMS實現機制上有什麼區別呢?

data model上的區別

這 裡引用了一副文獻【1】中的圖。從圖中可以看到,key-value存儲相比RDBMS,一個很大的區別就是它沒有schema。在RDBMS 中,schema所代表的其實就是對數據的約束,包括數據之間的關係(relationship),和數據的完整性(integrity),比如 RDBMS中對於某個數據屬性會要求它的數據類型是確定的(整數或者字符串等等),數據的範圍也是確定的(0~255等等),而這些在key-value store中都沒有。在key-value存儲中,對於某個key,value可以是任意的數據類型。正如圖中所說,「No relationships are explicitly defined」。

data processing上的區別

上面所 提的兩種data model之間的差異是非常顯而易見的,而這裡的區別卻並不常被提及。在RDBMS中,數據的處理都是一個個的事務(transaction),遵循 ACID的原則。而在很多的key-value存儲系統中,並不支持事務的處理。在解釋這一點前,先介紹一下Brewer和他的CAP理論。
Brewer 現在是UC Berkeley的一個教授,不過他的歷史可就牛了。在google出現之前,最牛的搜索引擎公司叫做Inktomi,而Brewer就是這家公司的 Founder。Inktomi也是在一個大的計算機集群上構建搜索引擎的,而Brewer根據Inktomi的經驗總結出了CAP理論,就是下面這幅圖 (來自文獻【3】):


這 幅圖的內容就是,對於一個系統,consistency(數據一致性),Availability(可用性),Partitions(網絡可分性)這三者 只能同時滿足其中的兩個。用CAP理論來解釋RDBMS,它滿足了Consistency和Availability,但正是因為如此,所以它在 Partition上就很難做得好。而對於很多的key-value形式的存儲系統而言,它更強調的是Availability和Network Partition,所以在Consistency上做了弱化。例如,Amazon的Dynamo(SimpleDB的底層系統),它就不支持事務,為了 高可用性而犧牲了數據的一致性「Dynamo targets applications that operate with weaker consistency (the  「C」  in  ACID)  if  this  results  in  high  availability」(見文獻【4】)。當然,需要指出的是,CAP理論並不是一個被證明了的定理,它只是一個經驗型的結論,在這裡是用CAP來更 容易的解釋為什麼很多key-value store不提供ACID。關於CAP更多的信息見 和文獻【3】。
另外需要指出的是,並非所有的key-value store都不支持事務,還是有部分系統支持ACID的,只是它已經不再是一個標準了。

接口層的區別

這也是一個相對顯而易見的區別。在所有RDBMS中,採用的都是SQL語言對數據進行訪問。一方面,SQL對於數據的查詢功能非常的強大,另一方面,由於所 有的RDBMS都支持SQL查詢,所以可移植性很強。而在key-value store中,對於數據的操作使用的都是自定義的一些API,而且支持的查詢也比較簡單。

優勢和劣勢

正如前面所 反覆提及的,key-value store最大的特點就是它的可擴展性(scalability),這也就是它最大的優勢。所謂的scalability,在我看來這裡包括了兩方面內 容。一方面,是指key-value store可以支持極大的數據的存儲,它的分佈式的架構決定了只要有更多的機器,就能夠保證存儲更多的數據。另一方面,是指它可以支持數量很多的並發的查 詢。對於RDBMS,一般幾百個並發的查詢就可以讓它很吃力了,而一個key-value store,可以很輕鬆的支持上千的並發查詢。
至於 key-value store的缺陷,文獻【1】提出了幾點,我認為還是很中肯的。例如,由於key-value store中沒有schema,所以它是不提供數據之間的關係和數據的完備性的,所有的這些東西都落到了應用程序一端,其實也就是開發人員的頭上。這無疑 加重了開發人員的負擔。在比如,在RDBMS中,需要設定每個表和表之間的關係,這其實是一個數據建模的過程(data modeling process)。當數據建模完成後,其實這個數據庫就和應用程序是獨立的了(application-independent),這就意味著別的程序可 以在不改變數據模型的前提下使用相同的數據集。但在key-value store中,由於沒有這麼一個數據模型,不同的應用程序需要重複進行這個過程。  
此外,我認為key-value store最大的一個缺點在於它的接口是不熟悉的。這阻礙了開發人員可以很快就順利的用上它。當然,現在有種做法,就是在key-value store上再加上一個類SQL語句的抽象接口層,從而使得開發人員可以用他們熟悉的方式(SQL)來操作key-value store。但由於畢竟RDBMS和key-value store的底層實現有著很大的不同,這種抽象接口層或多或少的還是受到了限制。

結語

文獻【7】中給出了當前比較常見的key-value的存儲系統,並逐一簡要介紹了它們各自的特點。感興趣的人可以去看看,這裡就不羅列了。

總的來說,我認為key-value store是未來的一種趨勢,但它並不足以完全取代RDBMS。只有當你的系統對於存儲的可擴展性要求很高時,才應該去考慮使用key-value這種解決方案。對於一般的應用,RDBMS還是最好的選擇。

 

参考文献:
【1】 
【2】
【3】
【4】Dynamo: Amazon’s Highly Available Key-value Store 
【5】 
【6】
【7】