NoSQL在2010年風生水起,大大小小的Web站點在追求高性能高可靠性方面,不由自主都選擇了NoSQL技術作為優先考慮的方面。今年伊始,InfoQ中文站有幸邀請到鳳凰網的孫立先生,為大家分享他之於NoSQL方面的經驗和體會。 非常榮幸能受邀在InfoQ開闢這樣一個關於NoSQL的專欄,InfoQ是 ...
NoSQL在2010年風生水起,大大小小的Web站點在追求高性能高可靠性方面,不由自主都選擇了NoSQL技術作為優先考慮的方面。今年伊始,InfoQ中文站有幸邀請到鳳凰網的孫立先生,為大家分享他之於NoSQL方面的經驗和體會。
非常榮幸能受邀在InfoQ開闢這樣一個關於NoSQL的專欄,InfoQ是我非常尊重的一家技術媒體,同時我也希望藉助InfoQ,在國內推動NoSQL的發展,希望跟我一樣有興趣的朋友加入進來。這次的NoSQL專欄系列將先整體介紹NoSQL,然後介紹如何把NoSQL運用到自己的項目中合適的場景中,還會適當地分析一些成功案例,希望有成功使用NoSQL經驗的朋友給我提供一些線索和信息。
NoSQL的分類
NoSQL僅僅是一個概念,NoSQL資料庫根據數據的存儲模型和特點分為很多種類。
類型 |
部分代表 |
特點 |
列存儲 |
Hbase Cassandra Hypertable |
顧名思義,是按列存儲數據的。最大的特點是方便存儲結構化和半結構化數據,方便做數據壓縮,對針對某一列或者某幾列的查詢有非常大的IO優勢。 |
文檔存儲 |
MongoDB CouchDB |
文檔存儲一般用類似json的格式存儲,存儲的內容是文檔型的。這樣也就有有機會對某些欄位建立索引,實現關係資料庫的某些功能。 |
key-value存儲 |
Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis |
可以通過key快速查詢到其value。一般來說,存儲不管value的格式,照單全收。(Redis包含了其他功能) |
圖存儲 |
Neo4J FlockDB |
圖形關係的最佳存儲。使用傳統關係資料庫來解決的話性能低下,而且設計使用不方便。 |
對象存儲 |
db4o Versant |
通過類似面向對象語言的語法操作資料庫,通過對象的方式存取數據。 |
xml資料庫 |
Berkeley DB XML Ba*** |
高效的存儲XML數據,並支持XML的內部查詢語法,比如XQuery,Xpath。 |
選擇合適的NoSQL
如此多類型的NoSQL,而每種類型的NoSQL又有很多,選擇也可能有多種,隨著業務場景,需求的變更可能選擇又會變化。我們常常需要根據如下情況考慮:
(1)數據結構特點。包括結構化、半結構化、欄位是否可能變更、是否有大文本欄位、數據欄位是否可能變化。
(2)寫入特點。包括insert比例、update比例、是否經常更新數據的某一個小欄位、原子更新需求。
(3) 查詢特點。包括查詢的條件、查詢熱點的範圍。比如用戶信息的查詢,可能就是隨機的,而新聞的查詢就是按照時間,越新的越頻繁。
NoSQL和關係資料庫結合
舉個簡單的例子,比如用戶評論的存儲,評論大概有主鍵id、評論的對象aid、評論內容content、用戶uid等欄位。我們能確定的是評論內容content肯定不會在資料庫中用where content=’’查詢,評論內容也是一個大文本欄位。那麼我們可以把 主鍵id、評論對象aid、用戶id存儲在資料庫,評論內容存儲在NoSQL,這樣資料庫就節省了存儲content占用的磁碟空間,從而節省大量IO,對content也更容易做Cache。
//從MySQL中查詢出評論主鍵id列表
commentIds=DB.query("SELECT id FROM comments where aid='評論對象id' LIMIT 0,20");
//根據主鍵id列表,從NoSQL取回評論實體數據
CommentsList=NoSQL.get(commentIds);
解決辦法:
將MYSQL裡面的某個大欄位存儲到NOSQL中。關係還是繼續存儲在關係型數據裡面。NOSQL只是存儲簡單的關係及實體內容。
NoSQL代替MySQL
在某些應用場合,比如一些配置的關係鍵值映射存儲、用戶名和密碼的存儲、Session會話存儲等等,用NoSQL完全可以替代MySQL存儲。不但具有更高的性能,而且開發也更加方便。http://hovertree.com/menu/db/
NoSQL概念
隨著web2.0的快速發展,非關係型、分散式數據存儲得到了快速的發展,它們不保證關係數據的ACID特性。NoSQL概念在2009年被提了出來。NoSQL最常見的解釋是“non-relational”,“Not Only SQL”也被很多人接受。(“NoSQL”一詞最早於1998年被用於一個輕量級的關係資料庫的名字。)
NoSQL被我們用得最多的當數key-value存儲,當然還有其他的文檔型的、列存儲、圖型資料庫、xml資料庫等。在NoSQL概念提出之前,這些資料庫就被用於各種系統當中,但是卻很少用於web互聯網應用。比如cdb、qdbm、bdb資料庫。
傳統關係資料庫的瓶頸
傳統的關係資料庫具有不錯的性能,高穩定型,久經歷史考驗,而且使用簡單,功能強大,同時也積累了大量的成功案例。在互聯網領域,MySQL成為了絕對靠前的王者,毫不誇張的說,MySQL為互聯網的發展做出了卓越的貢獻。
在90年代,一個網站的訪問量一般都不大,用單個資料庫完全可以輕鬆應付。在那個時候,更多的都是靜態網頁,動態交互類型的網站不多。
到了最近10年,網站開始快速發展。火爆的論壇、博客、sns、微博逐漸引領web領域的潮流。在初期,論壇的流量其實也不大,如果你接觸網路比較早,你可能還記得那個時候還有文本型存儲的論壇程式,可以想象一般的論壇的流量有多大。
Memcached+MySQL
後來,隨著訪問量的上升,幾乎大部分使用MySQL架構的網站在資料庫上都開始出現了性能問題,web程式不再僅僅專註在功能上,同時也在追求性能。程式員們開始大量的使用緩存技術來緩解資料庫的壓力,優化資料庫的結構和索引。開始比較流行的是通過文件緩存來緩解資料庫壓力,但是當訪問量繼續增大的時候,多台web機器通過文件緩存不能共用,大量的小文件緩存也帶了了比較高的IO壓力。在這個時候,Memcached就自然的成為一個非常時尚的技術產品。
Memcached作為一個獨立的分散式的緩存伺服器,為多個web伺服器提供了一個共用的高性能緩存服務,在Memcached伺服器上,又發展了根據hash演算法來進行多台Memcached緩存服務的擴展,然後又出現了一致性hash來解決增加或減少緩存伺服器導致重新hash帶來的大量緩存失效的弊端。當時,如果你去面試,你說你有Memcached經驗,肯定會加分的。
Mysql主從讀寫分離
由於資料庫的寫入壓力增加,Memcached只能緩解資料庫的讀取壓力。讀寫集中在一個資料庫上讓資料庫不堪重負,大部分網站開始使用主從複製技術來達到讀寫分離,以提高讀寫性能和讀庫的可擴展性。Mysql的master-slave模式成為這個時候的網站標配了。
分表分庫
隨著web2.0的繼續高速發展,在Memcached的高速緩存,MySQL的主從複製,讀寫分離的基礎之上,這時MySQL主庫的寫壓力開始出現瓶頸,而數據量的持續猛增,由於MyISAM使用表鎖,在高併發下會出現嚴重的鎖問題,大量的高併發MySQL應用開始使用InnoDB引擎代替MyISAM。同時,開始流行使用分表分庫來緩解寫壓力和數據增長的擴展問題。這個時候,分表分庫成了一個熱門技術,是面試的熱門問題也是業界討論的熱門技術問題。也就在這個時候,MySQL推出了還不太穩定的表分區,這也給技術實力一般的公司帶來了希望。雖然MySQL推出了MySQL Cluster集群,但是由於在互聯網幾乎沒有成功案例,性能也不能滿足互聯網的要求,只是在高可靠性上提供了非常大的保證。
MySQL的擴展性瓶頸
在互聯網,大部分的MySQL都應該是IO密集型的,事實上,如果你的MySQL是個CPU密集型的話,那麼很可能你的MySQL設計得有性能問題,需要優化了。大數據量高併發環境下的MySQL應用開發越來越複雜,也越來越具有技術挑戰性。分表分庫的規則把握都是需要經驗的。雖然有像淘寶這樣技術實力強大的公司開發了透明的中間件層來屏蔽開發者的複雜性,但是避免不了整個架構的複雜性。分庫分表的子庫到一定階段又面臨擴展問題。還有就是需求的變更,可能又需要一種新的分庫方式。
MySQL資料庫也經常存儲一些大文本欄位,導致資料庫表非常的大,在做資料庫恢復的時候就導致非常的慢,不容易快速恢複數據庫。比如1000萬4KB大小的文本就接近40GB的大小,如果能把這些數據從MySQL省去,MySQL將變得非常的小。
關係資料庫很強大,但是它並不能很好的應付所有的應用場景。MySQL的擴展性差(需要複雜的技術來實現),大數據下IO壓力大,表結構更改困難,正是當前使用MySQL的開發人員面臨的問題。
NOSQL的優勢
易擴展
資料庫種類繁多,但是一個共同的特點都是去掉關係資料庫的關係型特性。數據之間無關係,這樣就非常容易擴展。也無形之間,在架構的層面上帶來了可擴展的能力。
大數據量,高性能
NoSQL資料庫都具有非常高的讀寫性能,尤其在大數據量下,同樣表現優秀。這得益於它的無關係性,資料庫的結構簡單。一般MySQL使用Query Cache,每次表的更新Cache就失效,是一種大粒度的Cache,在針對web2.0的交互頻繁的應用,Cache性能不高。而NoSQL的Cache是記錄級的,是一種細粒度的Cache,所以NoSQL在這個層面上來說就要性能高很多了。
靈活的數據模型
NoSQL無需事先為要存儲的數據建立欄位,隨時可以存儲自定義的數據格式。而在關係資料庫里,增刪欄位是一件非常麻煩的事情。如果是非常大數據量的表,增加欄位簡直就是一個噩夢。這點在大數據量的web2.0時代尤其明顯。
高可用
NoSQL在不太影響性能的情況,就可以方便的實現高可用的架構。比如Cassandra,HBase模型,通過複製模型也能實現高可用。
總結
NoSQL資料庫的出現,彌補了關係數據(比如MySQL)在某些方面的不足,在某些方面能極大的節省開發成本和維護成本。
MySQL和NoSQL都有各自的特點和使用的應用場景,兩者的緊密結合將會給web2.0的資料庫發展帶來新的思路。讓關係資料庫關註在關係上,NoSQL關註在存儲上。
http://www.cnblogs.com/roucheng/