NoSQL解決方案比較-(轉載)

http://www.distream.org/?p=10html

NoSQL解決方案比較redis

NoSQL Solution: Evaluation and Comparison: MongoDB vs Redis, Tokyo Cabinet, and Berkeley DBsql

你也許認爲這是NoSQL (Not Only SQL)廣告宣傳的另外一個博客。mongodb

是,這的確是。數據庫

可是若是這個時候你仍就爲尋找一個可行的NoSQL解決方案而苦惱,讀完這篇後你就知道該作什麼了。apache

當我之前參與Perfect Market的內容處理平臺時,我拼命地嘗試尋找一個極端快速(從延時和處理時間上)和可擴展的NoSQL數據庫方案,去支持簡單地鍵/值查詢。緩存

在開始前我預約義了需求:網絡

快速數據插入(Fast data insertion)。有些數據集可能包含上億的行(KV鍵值對),雖然每行數據很小,但若是數據插入很慢,那將這個數據集傳入數據庫將須要花幾天時間,這是不可接受的。大數據集上的快速隨機讀取(Extermely fast random reads on large datesets)。在全部數據集上的一致的讀寫速度。這個意思是說,讀寫速度不能由於數據如何保持和index如何組織就在某個數據量上擁有很好的值,讀寫速度應該在全部的數據量上均衡。有效的數據存儲。原始的數據大小和數據被導入數據庫中的大小應該相差不大。很好的擴展性。咱們在EC2的內容處理節點可能產生大量的併發線程訪問數據節點,這須要數據節點能很好的擴展。同時,不是全部的數據集是隻讀的,某些數據節點必須在合適的寫負載下很好的擴展。容易維護。咱們的內容處理平臺利用了本地和EC2資源。在不一樣的環境裏,同時打包代碼,設置數據,和運行不一樣類型的節點是不容易的。預期的方案必須很容易維護,以便知足高自動化的內容處理系統。擁有網絡接口。只用於庫文件的方案是不充足的。穩定。必須的。併發

我開始尋找時毫無偏見,由於我從未嚴格地使用過NoSQL產品。通過同事的推薦,而且閱讀了一堆的博客後,驗證的旅程開始於Tokyo Cabinet,而後是 Berkeley DB庫, MemcacheDB, Project Voldemort, Redis, MongoDBoracle

其實還存在不少流行的可選項,好比Cassandra, HBase, CouchDB…還有不少你能列出來的,但咱們沒沒有必要去嘗試,由於咱們選擇的那些已經工做得很好。結果出來至關的不錯,這個博客共享了我測試的一些細節。

爲了解釋選擇了哪一個以及爲何選擇這個,我採納了同事Jay Budzik(CTO)的建議,建立了一張表來比較全部方案在每個需求上的狀況。雖然這張表是一個過後的事情,但它展現了基本原理,同時也會對處於決策的人們帶來幫助。

請注意這個表不是100%的客觀和科學。它結合了測試結果和個人直覺推導。頗有趣,我開始驗證時沒有偏見,但測試完全部的後,我也許有了一點偏愛(特別是基於個人測試用例)。

另外一個須要注意的是這裏的磁盤訪問是I/O密集性工做負載裏最慢的一個操做。相對於內存訪問, 這是毫秒與納秒的關係。爲了處理包含上億行的數據集合,你最好給你的機器配置足夠的內存。若是你的機器只有4G內存而你想處理50GB的數據且指望較好的速度,那你要麼搖晃你的機器,要麼用個更好的,不然只能扔到下面全部的方案,由於它們都不會工做。

nosql

看了這張表,你也許能猜到我選了哪一個方案。不要着急,讓我詳細說明每個方案。

Tokyo Cabinet (TC)是一個很是好的方案也是我第一個驗證的。我如今仍然很喜歡它,雖然這不是我最後選擇的。它的質量驚人的高。哈希表數據庫對於小數據集(低於2千萬行)驚人的快,水平擴展能力也很好。TC的問題是當數據量增長時,讀寫的性能降低的特別快。

Berkeley DB(BDB)MemcacheDB (BDB的遠程接口)是一個較老的結合物。若是你熟悉BDB,而且不是很是依賴速度和功能集合,好比你願意等幾天去加載大數據集到數據庫裏而且你接受通常但不優秀的讀速度,你仍可使用它。對於咱們,事實是它花了太長的時間來加載初始數據。

Project Voldemort是惟一一個基於Java和雲計算的方案。在驗證前我有很高的指望,可是結果卻有點失望,緣由是:

BDB Java版本讓個人數據膨脹得太厲害(大概是1比4,而TC只有1比1.3)。基本上存儲效率很是低。對於大數據集,它就是災難。當數據變得很大的時候,插入速度下降得很快。當大數據集被加載時偶爾因爲沒法預測的異常而崩潰。

當數據膨脹得太厲害而且偶爾系統崩潰時,數據加載尚未完成。只有四分之一的數據被傳播,它讀速度還能夠但不出色。在這個時候我想我最好放棄它。不然,除了上面列的那些須要優化,JVM可能讓我操更多的心讓個人頭髮灰的更多,雖然我已經爲Sun工做了五年。

Redis是一個極好的緩存解決方案,咱們也採用了它。Redis將全部的哈希表存在內存裏,背後有一個線程按照預設的時間定時將哈希表中的快照存到磁盤上。若是系統重啓,它能夠從磁盤上加載快照到內存,就像啓動時保溫的緩存。它要花幾分鐘來恢復20GB的數據,固然也依賴你的磁盤速度。這是一個很是好的主意,Redis有一個合適的實現。

可是在咱們的用例裏,它工做得並很差。後臺的保存程序仍妨礙了咱們,特別是當哈希表變得更大時。我擔憂它會負面地影響讀速度。使用logging style persistence而不是保存整個快照,能夠減緩這些數據轉存的影響,可是數據大小將會膨脹,若是太頻繁,將最終影響恢復時間。單線程模式聽起來不是可伸縮的,雖然在個人測試裏它水平方向擴展的很好:支持幾百個併發讀。

另外一個事情干擾個人是Redis的整個數據集必須適合物理內存。這點使得它不容易被管理,象在咱們這樣在不一樣的產品週期形成的多樣化的環境裏。Redis最近的版本可能減輕了這方面的問題。

MongoDB是至今我最喜歡的,在我所驗證的全部解決方案中,它是勝出者,咱們的產品也正在使用。

MongoDB提供了不一樣尋常的插入速度,可能緣由是延遲寫入和快速文件擴展(每一個集合結構有多個文件)。只要你擁有足夠的內存,上億的數據行能在幾小時內插入,而不是幾天。我應該在這提供確切的數據,但數據太具體(與咱們的項目有關)不見得對別人有幫助。但相信我,MongoDB提供了很是快的大數據量插入操做。

MongoDB使用內存映射文件,它通常花納秒級的時間來解決微小的頁面錯誤,讓文件系統緩存的頁面映射到MongoDB的內存空間。相比於其它方案,MongoDB不會和頁面緩存競爭,由於它使用和只讀塊相同的內存。在其它方案裏,若是你分配給太多的內存給工具自身,那盒子裏的頁面緩存就變得不多,而且通常來講想讓工具的緩存徹底地預熱不是很容易,或者沒有一個有效地方法(你絕對不想事先去從數據庫裏讀取每一行)。

對於MongoDB,能夠很是容易地作一些簡單的技巧讓全部的數據加載到頁面緩存。一旦在這個狀態,MongoDB就很像Redis,在隨機讀上有較好的性能。

在我另外一個測試中,200併發客戶在大數據集(上億行數據)作持續的隨機讀取,MongoDB表現了整體上的400,000QPS。測試中,數據在頁面緩存裏預熱(事先加載)。在隨後的測試中,MongoDB一樣顯示了在適度的寫負載下擁有很是好的隨機讀取速度。在相對來講一個大的負載下,咱們壓縮了數據而後將它存入MongoDB,這樣就減小了數據大小因此更多的東西能放入內存。

MongoDB提供了一個方便的客戶端工具(相似MySQL的),很是好用。它也提供了高級的查詢功能,處理大型文檔的功能,可是咱們尚未用到這些。MongoDB很是穩定,基本不須要維護,處理你可能要監控數據量增大時的內存使用狀況。MongoDB對不一樣的語言有很好的客戶端API支持,這使得它很容易使用。我不用列舉它全部的功能,但我想你會獲得你想要的。

雖然MongoDB方案能夠知足大多數NoSQL的需求,但它不是惟一的一個。若是你只須要處理小數據量,Tokyo Cabinet最合適。若是你須要處理海量數據(PB千兆兆)並擁有不少機器,並且延時不是個問題,你也不強求極好的響應時間,那麼Cassandra和HBase均可以勝任。

最後,若是你仍須要考慮事務處理,那就不要弄NoSQL, 直接用Oracle。

注:這篇文章寫得實在是精彩,將nosql的幾種數據庫比較的很細。因此忍不住轉載的。開頭的兩個連接爲原文出處。以及翻譯版。

相關文章
相關標籤/搜索