隨着互聯網web2.0網站的興起,非關係型的數據庫如今成了一個極其熱門的新領域,非關係數據庫產品的發展很是迅速。而傳統的關係數據庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了不少難以克服的問題,例如: git
1、High performance - 對數據庫高併發讀寫的需求
web2.0網站要根據用戶個性化信息來實時生成動態頁面和提供動態信息,因此基本上沒法使用動態頁面靜態化技術,所以數據庫併發負載很是高,每每要達到每秒上萬次讀寫請求。關係數據庫應付上萬次SQL查詢還勉強頂得住,可是應付上萬次SQL寫數據請求,硬盤IO就已經沒法承受了。其實對於普通的BBS網站,每每也存在對高併發寫請求的需求,例如像JavaEye網站的實時統計在線用戶狀態,記錄熱門帖子的點擊次數,投票計數等,所以這是一個至關廣泛的需求。
2、Huge Storage - 對海量數據的高效率存儲和訪問的需求
相似Facebook,twitter,Friendfeed這樣的SNS網站,天天用戶產生海量的用戶動態,以Friendfeed爲例,一個月就達到了2.5億條用戶動態,對於關係數據庫來講,在一張2.5億條記錄的表裏面進行SQL查詢,效率是極其低下乃至不可忍受的。再例如大型web網站的用戶登陸系統,例如騰訊,盛大,動輒數以億計的賬號,關係數據庫也很難應付。 github
3、High Scalability && High Availability- 對數據庫的高可擴展性和高可用性的需求
在基於web的架構當中,數據庫是最難進行橫向擴展的,當一個應用系統的用戶量和訪問量與日俱增的時候,你的數據庫卻沒有辦法像web server和app server那樣簡單的經過添加更多的硬件和服務節點來擴展性能和負載能力。對於不少須要提供24小時不間斷服務的網站來講,對數據庫系統進行升級和擴展是很是痛苦的事情,每每須要停機維護和數據遷移,爲何數據庫不能經過不斷的添加服務器節點來實現擴展呢?
在上面提到的「三高」需求面前,關係數據庫遇到了難以克服的障礙,而對於web2.0網站來講,關係數據庫的不少主要特性卻每每無用武之地,例如:
一、數據庫事務一致性需求 web
不少web實時系統並不要求嚴格的數據庫事務,對讀一致性的要求很低,有些場合對寫一致性要求也不高。所以數據庫事務管理成了數據庫高負載下一個沉重的負擔。
二、數據庫的寫實時性和讀實時性需求 數據庫
對關係數據庫來講,插入一條數據以後馬上查詢,是確定能夠讀出來這條數據的,可是對於不少web應用來講,並不要求這麼高的實時性,比方說我(JavaEye的robbin)發一條消息以後,過幾秒乃至十幾秒以後,個人訂閱者纔看到這條動態是徹底能夠接受的。
三、對複雜的SQL查詢,特別是多表關聯查詢的需求 json
任何大數據量的web系統,都很是忌諱多個大表的關聯查詢,以及複雜的數據分析類型的複雜SQL報表查詢,特別是SNS類型的網站,從需求以及產品設計角度,就避免了這種狀況的產生。每每更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能被極大的弱化了。
所以,關係數據庫在這些愈來愈多的應用場景下顯得不那麼合適了,爲了解決這類問題的非關係數據庫應運而生,如今這兩年,各類各樣非關係數據庫,特別是鍵值數據庫(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
2、知足海量存儲需求和訪問的面向文檔的數據庫:MongoDB,CouchDB
3、知足高可擴展性和可用性的面向分佈式計算的數據庫:Cassandra,Voldemort
四,幾種主流NoSQL數據庫
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。
MongoDB
MongoDB是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。他支持的數據結構很是鬆散,是相似json的bjson格式,所以能夠存儲比較複雜的數據類型。Mongo最大的特色是他支持的查詢語言很是強大,其語法有點相似於面向對象的查詢語言,幾乎能夠實現相似關係數據庫單表查詢的絕大部分功能,並且還支持對數據創建索引。
Mongo主要解決的是海量數據的訪問效率問題,根據官方的文檔,當數據量達到50GB以上的時候,Mongo的數據庫訪問速度是MySQL的10倍以上。Mongo的併發讀寫效率不是特別出色,根據官方提供的性能測試代表,大約每秒能夠處理0.5萬-1.5次讀寫請求。
由於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如出一轍,功能很是強大易用。