NoSQL數據庫探討之一 - 爲何要用非關係數據庫?

隨着互聯網web2.0網站的興起,非關係型的數據庫如今成了一個極其熱門的新領域,非關係數據庫產品的發展很是迅速。而傳統的關係數據庫在應付 web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了不少難以克服的問題,例如:node

一、High performance - 對數據庫高併發讀寫的需求 web2.0網站要根據用戶個性化信息來實時生成動態頁面和提供動態信息,因此基本上沒法使用動態頁面靜態化技術,所以數據庫併發負載很是高,往 往要達到每秒上萬次讀寫請求。關係數據庫應付上萬次SQL查詢還勉強頂得住,可是應付上萬次SQL寫數據請求,硬盤IO就已經沒法承受了。其實對於普通的 BBS網站,每每也存在對高併發寫請求的需求,例如像JavaEye網站的實時統計在線用戶狀態,記錄熱門帖子的點擊次數,投票計數等,所以這是一個至關 廣泛的需求。git

二、Huge Storage - 對海量數據的高效率存儲和訪問的需求 相似Facebook,twitter,Friendfeed這樣的SNS網站,天天用戶產生海量的用戶動態,以Friendfeed爲例,一個 月就達到了2.5億條用戶動態,對於關係數據庫來講,在一張2.5億條記錄的表裏面進行SQL查詢,效率是極其低下乃至不可忍受的。再例如大型web網站 的用戶登陸系統,例如騰訊,盛大,動輒數以億計的賬號,關係數據庫也很難應付。github

三、High Scalability &&High Availability- 對數據庫的高可擴展性和高可用性的需求 在基於web的架構當中,數據庫是最難進行橫向擴展的,當一個應用系統的用戶量和訪問量與日俱增的時候,你的數據庫卻沒有辦法像web server和app server那樣簡單的經過添加更多的硬件和服務節點來擴展性能和負載能力。對於不少須要提供24小時不間斷服務的網站來講,對數據庫系統進行升級和擴展 是很是痛苦的事情,每每須要停機維護和數據遷移,爲何數據庫不能經過不斷的添加服務器節點來實現擴展呢?web

在上面提到的「三高」需求面前,關係數據庫遇到了難以克服的障礙,而對於web2.0網站來講,關係數據庫的不少主要特性卻每每無用武之地,例 如:數據庫

一、數據庫事務一致性需求 不少web實時系統並不要求嚴格的數據庫事務,對讀一致性的要求很低,有些場合對寫一致性要求也不高。所以數據庫事務管理成了數據庫高負載下一個 沉重的負擔。json

二、數據庫的寫實時性和讀實時性需求 對關係數據庫來講,插入一條數據以後馬上查詢,是確定能夠讀出來這條數據的,可是對於不少web應用來講,並不要求這麼高的實時性,比方說我 (JavaEye的robbin)發一條消息以後,過幾秒乃至十幾秒以後,個人訂閱者纔看到這條動態是徹底能夠接受的。後端

三、對複雜的SQL查詢,特別是多表關聯查詢的需求 任何大數據量的web系統,都很是忌諱多個大表的關聯查詢,以及複雜的數據分析類型的複雜SQL報表查詢,特別是SNS類型的網站,從需求以及產 品設計角度,就避免了這種狀況的產生。每每更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。ruby

所以,關係數據庫在這些愈來愈多的應用場景下顯得不那麼合適了,爲了解決這類問題的非關係數據庫應運而生,如今這兩年,各類各樣非關係數據庫,特 別是鍵值數據庫(Key-Value Store DB)風起雲涌,多得讓人眼花繚亂。前不久國外剛剛舉辦了NoSQL Conference,各路NoSQL數據庫紛紛亮相,加上未亮相可是名聲在外的,起碼有超過10 個開源的NoSQLDB,例如:服務器

Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB, ......網絡

這些NoSQL數據庫,有的是用C/C++編寫的,有的是用Java編寫的,還有的是用Erlang編寫的,每一個都有本身的獨到之處,看都看不過 來了,我(robbin)也只能從 中挑選一些比較有特點,看起來更有前景的產品學習和了解一下。這些NoSQL數據庫大體能夠分爲如下的三類:

1、知足極高讀寫性能需求的Kye-Value數據 庫:Redis,Tokyo Cabinet, Flare

高性能Key-Value數據庫的主要特色就是具備極高的併發讀寫性能,Redis,Tokyo Cabinet, Flare,這3個Key-Value DB都是用C編寫的,他們的性能都至關出色,但出了出色的性能,他們還有本身獨特的功能:

一、Redis Redis是一個很新的項目,剛剛發佈了1.0版本。Redis本質上是一個Key-Value類型的內存數據庫,很像memcached,整個 數據庫通通加載在內存當中進行操做,按期經過異步操做把數據庫數據flush到硬盤上進行保存。由於是純內存操做,Redis的性能很是出色,每秒能夠處 理超過10萬次讀寫操做,是我知道的性能最快的Key-Value DB。

Redis的出色之處不只僅是性能,Redis最大的魅力是支持保存List鏈表和Set集合的數據結構,並且還支持對List進行各類操做,例 如從List兩端push和pop數據,取List區間,排序等等,對Set支持各類集合的並集交集操做,此外單個value的最大限制是1GB,不像 memcached只能保存1MB的數據,所以Redis能夠用來實現不少有用的功能,比方說用他的List來作FIFO雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set能夠作高性能的tag系統等等。另外Redis也能夠對存入的Key-Value設置expire時間,所以也能夠被看成一 個功能增強版的memcached來用。

Redis的主要缺點是數據庫容量受到物理內存的限制,不能用做海量數據的高性能讀寫,而且它沒有原生的可擴展機制,不具備scale(可擴展) 能力,要依賴客戶端來實現分佈式讀寫,所以Redis適合的場景主要侷限在較小數據量的高性能操做和運算上。目前使用Redis的網站有 github,Engine Yard。

二、Tokyo Cabinet和Tokoy Tyrant TC和TT的開發者是日本人Mikio Hirabayashi,主要被用在日本最大的SNS網站mixi.jp上,TC發展的時間最先,如今已是一個很是成熟的項目,也是Kye-Value 數據庫領域最大的熱點,如今被普遍的應用在不少不少網站上。TC是一個高性能的存儲引擎,而TT提供了多線程高併發服務器,性能也很是出色,每秒能夠處理 4-5萬次讀寫操做。

TC除了支持Key-Value存儲以外,還支持保存Hashtable數據類型,所以很像一個簡單的數據庫表,而且還支持基於column的條 件查詢,分頁查詢和排序功能,基本上至關於支持單表的基礎查詢功能了,因此能夠簡單的替代關係數據庫的不少操做,這也是TC受到你們歡迎的主要緣由之一, 有一個Ruby的項目miyazakiresistance將TT的hashtable的操做封裝成和ActiveRecord同樣 的操做,用起來很是爽。

TC/TT在mixi的實際應用當中,存儲了2000萬條以上的數據,同時支撐了上萬個併發鏈接,是一個久經考驗的項目。TC在保證了極高的併發 讀寫性能的同時,具備可靠的數據持久化機制,同時還支持相似關係數據庫表結構的hashtable以及簡單的條件,分頁和排序操做,是一個很棒的 NoSQL數據庫。

TC的主要缺點是在數據量達到上億級別之後,併發寫數據性能會大幅度降低,NoSQL: If Only It Was That Easy提到,他們發如今TC裏面插入1.6億條 2-20KB數據的時候,寫入性能開始急劇降低。看來是當數據量上億條的時候,TC性能開始大幅度降低,從TC做者本身提供的mixi數據來看,至少上千 萬條數據量的時候尚未遇到這麼明顯的寫入性能瓶頸。

這個是Tim Yang作的一個Memcached,Redis和Tokyo Tyrant的簡單的性能評測,僅供參考

三、Flare TC是日本第一大SNS網站mixi開發的,而Flare是日本第二大SNS網站green.jp開發的,有意思吧。Flare簡單的說就是給 TC添加了scale功能。他替換掉了TT部分,本身另外給TC寫了網絡服務器,Flare的主要特色就是支持scale能力,他在網絡服務端以前添加了 一個node server,來管理後端的多個服務器節點,所以能夠動態添加數據庫服務節點,刪除服務器節點,也支持failover。若是你的使用場景必需要讓TC可 以scale,那麼能夠考慮flare。

flare惟一的缺點就是他只支持memcached協議,所以當你使用flare的時候,就不能使用TC的table數據結構了,只能使用TC 的key-value數據結構存儲。

2、知足海量存儲需求和訪問的面向文檔的數據 庫:MongoDB,CouchDB

面向文檔的非關係數據庫主要解決的問題不是高性能的併發讀寫,而是保證海量數據存儲的同時,具備良好的查詢性能。MongoDB是用C++開發 的,而CouchDB則是Erlang開發的:

一、MongoDB MongoDB是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。他支持的數據結構很是鬆散,是 相似json的bjson格式,所以能夠存儲比較複雜的數據類型。Mongo最大的特色是他支持的查詢語言很是強大,其語法有點相似於面向對象的查詢語 言,幾乎能夠實現相似關係數據庫單表查詢的絕大部分功能,並且還支持對數據創建索引。

Mongo主要解決的是海量數據的訪問效率問題,根據官方的文檔,當數據量達到50GB以上的時候,Mongo的數據庫訪問速度是MySQL的 10倍以上。Mongo的併發讀寫效率不是特別出色,根據官方提供的性能測試代表,大約每秒能夠處理0.5萬-1.5次讀寫請求。對於Mongo的併發讀 寫性能,我(robbin)也打算有空的時候好好測試一下。

由於Mongo主要是支持海量數據存儲的,因此Mongo還自帶了一個出色的分佈式文件系統GridFS,能夠支持海量的數據存儲,但我也看到有 些評論認爲GridFS性能不佳,這一點仍是有待親自作點測試來驗證了。

最後因爲Mongo能夠支持複雜的數據結構,並且帶有強大的數據查詢功能,所以很是受到歡迎,不少項目都考慮用MongoDB來替代MySQL來 實現不是特別複雜的Web應用,比方說why we migrated from MySQL to MongoDB就是一個真實的從MySQL遷 移到MongoDB的案例,因爲數據量實在太大,因此遷移到了Mongo上面,數據查詢的速度獲得了很是顯著的提高。

MongoDB也有一個ruby的項目MongoMapper,是模仿Merb的DataMapper編寫的MongoDB的接口,使用起來很是簡 單,幾乎和DataMapper如出一轍,功能很是強大易用。

二、CouchDB CouchDB如今是一個很是有名氣的項目,彷佛不用多介紹了。可是我卻對CouchDB沒有什麼興趣,主要是由於CouchDB僅僅提供了基於 HTTP REST的接口,所以CouchDB單純從併發讀寫性能來講,是很是糟糕的,這讓我馬上拋棄了對CouchDB的興趣。

3、知足高可擴展性和可用性的面向分佈式計算的數據 庫:Cassandra,Voldemort

面向scale能力的數據庫其實主要解決的問題領域和上述兩類數據庫還不太同樣,它首先必須是一個分佈式的數據庫系統,由分佈在不一樣節點上面的數 據庫共同構成一個數據庫服務系統,而且根據這種分佈式架構來提供online的,具備彈性的可擴展能力,例如能夠不停機的添加更多數據節點,刪除數據節點 等等。所以像Cassandra經常被當作是一個開源版本的Google BigTable的替代品。Cassandra和Voldemort都是用Java開發的:

一、Cassandra Cassandra項目是Facebook在2008年開源出來的,隨後Facebook本身使用Cassandra的另一個不開源的分支,而 開源出來的Cassandra主要被Amazon的Dynamite團隊來維護,而且Cassandra被認爲是Dynamite2.0版本。目前除了 Facebook以外,twitter和digg.com都在使用Cassandra。

Cassandra的主要特色就是它不是一個數據庫,而是由一堆數據庫節點共同構成的一個分佈式網絡服務,對Cassandra的一個寫操做,會 被複制到其餘節點上去,對Cassandra的讀操做,也會被路由到某個節點上面去讀取。對於一個Cassandra羣集來講,擴展性能是比較簡單的事 情,只管在羣集裏面添加節點就能夠了。我看到有文章說Facebook的Cassandra羣集有超過100臺服務器構成的數據庫羣集。

Cassandra也支持比較豐富的數據結構和功能強大的查詢語言,和MongoDB比較相似,查詢功能比MongoDB稍弱一 些,twitter的平臺架構部門領導Evan Weaver寫了一篇文章介紹Cassandra:http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/, 有很是詳細的介紹。

Cassandra以單個節點來衡量,其節點的併發讀寫性能不是特別好,有文章說評測下來Cassandra每秒大約不到1萬次讀寫請求,我也看 到一些對這個問題進行質疑的評論,可是評價Cassandra單個節點的性能是沒有意義的,真實的分佈式數據庫訪問系統必然是n多個節點構成的系統,其並 發性能取決於整個系統的節點數量,路由效率,而不只僅是單節點的併發負載能力。

二、Voldemort Voldemort是個和Cassandra相似的面向解決scale問題的分佈式數據庫系統,Cassandra來自於Facebook這個 SNS網站,而Voldemort則來自於Linkedin這個SNS網站。提及來SNS網站爲咱們貢獻了n多的NoSQL數據庫,例如 Cassandar,Voldemort,Tokyo Cabinet,Flare等等。Voldemort的資料不是不少,所以我沒有特別仔細去鑽研,Voldemort官方給出Voldemort的併發讀 寫性能也很不錯,每秒超過了1.5萬次讀寫。

從Facebook開發Cassandra,Linkedin開發Voldemort,咱們也能夠大體看出國外大型SNS網站對於分佈式數據庫, 特別是對數據庫的scale能力方面的需求是多麼殷切。前面我(robbin)提到,web應用的架構當中,web層和app層相對來講都很容易橫向擴 展,惟有數據庫是單點的,極難scale,如今Facebook和Linkedin在非關係型數據庫的分佈式方面探索了一條很好的方向,這也是爲何如今 Cassandra這麼熱門的主要緣由。

現在,NoSQL數據庫是個使人很興奮的領域,老是不斷有新的技術新的產品冒出來,改變咱們已經造成的固有的技術觀念,我本身(robbin)稍 微瞭解了一些,就感受本身深深的沉迷進去了,能夠說NoSQL數據庫領域也是博大精深的,我(robbin)也只能淺嘗輒止,我(robbin)寫這篇文 章既是本身一點點鑽研心得,也是拋磚引玉,但願吸引對這個領域有經驗的朋友來討論和交流。

從我(robbin)我的的興趣來講,分佈式數據庫系統不是我能實際用到的技術,所以不打算花時間深刻,而其餘兩個數據領域(高性能 NoSQLDB和海量存儲NoSQLDB)都是我很感興趣的,特別是Redis,TT/TC和MongoDB這3個NoSQL數據庫,所以我接下來將寫三 篇文章分別詳細介紹這3個數據庫。

相關文章
相關標籤/搜索