【NOSQL】couchDB

couchDB是這兩年很受geek追捧的數據庫,作者曾是lotus開發人員。與傳統的關係型數據庫不同, 它號稱自己是文檔數據庫。所謂文檔數據庫,並不是說它只能存儲文本,事實上因爲它是一種schemal-less的概念。用過關係型數據庫的同學都知道, 數據表裏定義的每一個字段都定義爲一種類型:無論是int,char,datetime。但couchDB的字段只有三個:文檔ID、文檔版本號和內容。 內容字段可以看到是一個text類型的文本,裏面可以隨意定義數據,而不用關注數據類型,但數據必須以json的形式表示並存放。例如一個表述用戶的文檔 可以表示爲:[_id:1001, _rev:1-32443289, {'name':'wentrue', 'location':'beijing'}]。couchDB的底層是erlang語言,以RESTful API的格式提供服務,couchDB所有的讀寫能力都可以通過簡單的調用它的HTTP請求來實現。正因爲採用那麼一種統一且簡潔的服務接口,可以很方便地開發各種語言的客戶端,以方便不同程序員的使用。

couchDB的文檔不多,基本上主體都在它網站的overview和wiki了。這裏按照我的理解組織一遍,不敢冒”大全“之名,借”小全“一用尚可。 以下以幾個關鍵詞爲標籤簡要敘述。

優點:

couchDB的主要特點在於易用性及併發性。後者我的認識主要是來自erlang,因爲erlang是以易並行實現而著稱的,我自己並沒有測試 過。但對於易用性我是有着深刻體會。只要一搭好服務,你不但擁有了一個聽任你調遣的數據服務端,還擁有一個簡潔web server,如果你是在本地部署的,在瀏覽器上訪問http://localhost:5984/_utils/,你就可以看到一個管理與查詢的後臺, 在那個後臺,你基本能實現用其它客戶端能實現的所有事情。也就是說,即便你不懂編程語言,你可以在這個管理平臺自由發揮,當然如果你懂一些 javascript,那你就可以把couchDB玩轉了。

這個易用性意味着什麼?讓我們作個假設,你是一個網站開發人員,你有大量的數據需要存儲,但你又不想跟複雜的後臺邏輯打交道,或許你還不想過多地進 行後臺維護,那麼用couchDB,你可以直接用js調用數據,然後結合html+css把數據展現出來,再通過js把數據寫回去,這就實現了一個簡單的內容發佈系統,沒有任何後臺架構。實際上已經有很多用couchDB實現的網站。

技術概述:

couchDB的底層是一個B-tree的存儲結構,爲提高效率,所有的數據的插入或更新都是直接在樹的葉子節點添加,不刪除舊節點,通過版本號來 確定最新的數據--版本號還能用來解決併發寫的衝突。所以數據文件會越來越大,可以在適當地時間運行compact過程或replication過程,會 刪除舊文件,使得數據文件得到壓縮。

與mysql的對比(是什麼原因促使我把眼光暫時離開mysql):

1、couchDB的屬性可以靈活增刪,要增加一個新屬性只需要往數據字段多寫入一個屬性即可。mysql在數據量大了之後,再增刪字段會比較耗費 時間,在線操作更是讓人難以忍受的(視數據量大小有可能要鎖表幾十分鐘到一天);

2、文檔間屬性的不一致,如有些記錄可能有A屬性而有一些沒有,用mysql則只能把沒有該屬性的用戶的值置爲0或空,影響存儲與查詢;

3、 查詢效率,經常會需要對某個字段進行查詢,得到某個滿足條件的子集,用mysql要對每個字段的查詢都達到高效只能採用對該字段建索引的辦法,使得索引文 件變大,如果新增字段又要新建索引,建立索引也是一個鎖表又冗長的過程。couchDB應用map-reduce的方法使得計算量可以分散(注意:跟 google的那個不太一樣,這裏的map-reduce實際上還是在一臺機器完成,且沒有發現多個進程,沒有看到線程個數的配置,這是我感到最難解的, 難道還是單線程流水處理的?),雖然也是像沒有建索引的mysql一樣需要掃全表,但可以對常用的一些查詢建立永久索引,索引是隨數據的增長增量更新的, 減少查詢時間。

數據格式:

couchDB以json格式存儲數據,返回的數據也默認爲json格式,這對於前端的javascript處理是非常方便的。然而如果你用其它的 語言,比如python,獲取回來的數據量很大,用simplejson包去把這個龐大的json字符串解釋爲dict,這就有點費時間了。解決方法之一 是升級你的simplejson到最新版本,這樣速度可以提升幾倍,或者你用cjson,這樣格式轉換的時間就基本可以忽略不計。但cjson的接口與處 理跟simplejson有點不太一樣,如果你用couchdb-python作爲客戶端,需要對客戶端代碼作修改。另一個方法是要求服務端直接返回 list格式的數據,然後直接在python解釋,避過了json解釋一關,速度應該保證。list格式請求的API可以看這裏

緩存:

應該是有緩存的,因爲同樣的查詢,第二次再查時會比第一次快不少,在couchDB的數據目錄也能看到查詢生成的臨時文件。不過我估計主要的數據還 是在硬盤,因爲couchDB服務佔內存不多,數據不太可能都在裏面,而且依據第二次查詢的速度來看,不像是直接從內存取出來的,倒像是從硬盤現成拿數據 的速度。

更新機制(如何保持數據一致性):

上面說到couchDB每個文檔有三個字段,其中_rev代表該文檔的版本號,數據每更新一次,文檔的版本號也會更新一次。這個版本號對於保持數據 一致性有很重大的作用。上面談到couchDB把所有的屬性忽略schema都統一放在一個字段裏,那麼當有兩個程序同時修改這個字段時,就有可能造成先 寫入的數據被後寫入的數據覆蓋的現象,導致數據不一致。couchDB利用版本號來解決這個問題,當有程序需要修改一條數據時,它必須先把這個數據的版本 號讀出來,寫入的時候,連版本號一併寫入,此時couchDB會檢查該版本號是否與原數據的一致,如果一致則寫入,如果不一致,則說明數據在該程序讀出後 已經被修改過,couchDB會寫入不成功,返回一個衝突的信號,待客戶端程序處理。

分佈式:

現在couchDB(<1.0)並沒有內置分佈式處理機制。所以,官網中提倡的分佈式並保持數據一致性的解決方法是:你設置一個寫的 couchDB服務,然後把這份數據用replication過程同步拷貝到其它的機器,作爲讀服務。這樣的分佈式聽起來有點傻,但確實就是如此。所以, 信息的一致性其實是難以保證的,也即是說,你剛在網站上發佈了一個信息,刷新之後可能並不會馬上就能看到它。不知道將來couchDB的開發者會不會就這 方面進行努力,至少現在看到的計劃是還沒有包含更多的分佈式支持。

穩定性:

在網上的介紹中,穩定性是作爲它的一個feature來介紹的,但我在gentoo上直接用portage裝的couchDB0.9服務一週之內莫 名其妙地消失了三次,且在日誌裏沒有留下任何蜘絲馬跡。所以我對此持保留態度。

python客戶端:

因爲提供了簡易的RESTful接口,爲couchDB寫各種語言的客戶端可就容易多了,這裏列出了大量的客戶端。python客戶端主要有 couchdb-python和couchdbkit,我試驗中主要是使用了前者,使用中的問題是json的解釋效率。如果使用python自帶的 simplejson或json(>2.5)模塊來解釋,碰上一個大的字符串或dict,你就只能痛苦地等待了。我最初就是以爲couchDB極 慢,誰想其實是json解釋佔了大部分的時間。要解決這個問題,可以裝cjson,很快,但需要對couchdb-python的源代碼作改動;另一個選 擇是升級simplejson到最新版,速度會有極大的提升。

couchDB要做什麼(它的能與不能):

即使解決了json解釋的問題,純粹歸究到couchDB的問題時,你可不能對它的大數據量讀寫抱有太大的信心,畢竟它設計的初衷是前臺的併發應 用,並不是要讓你一次讀出或更新幾百萬條數據。我的試驗結果是,讀200W的數據(每條記錄並不大),第一次查詢大概幾分鐘,第二次一分鐘左右,更新 200W條記錄,你需要等待大於20分鐘。所以,目前爲止,如果你要作後臺批量讀寫,並且不能忍受這個速率,它可不是一個最好的選擇。同時在你更新數據的 過程中,數據文件的體積會逐漸變大,因爲數據都是追加到文件末尾的,舊數據並沒有刪除,所以用couchDB必須預備較大的硬盤空間,並且要定時運行 compact或replication過程,通過壓縮或拷貝來清除舊數據。

前景:

這兩年couchDB備受追捧,社區非常活躍,通常社區的活躍程度是影響一個開源軟件成敗的關鍵因素。couchDB吸引人的關鍵之處當然在於它提 出了一些對web數據存儲與索引的很好的方案,如果把關係型數據庫看作是一批有固定格式的電子表格的集合,那麼文檔型數據庫就是一批各色各樣的文檔的集 合。相對於關係型數據庫而言,文檔數據庫顯然更適合用於多樣而靈活的web數據。而couchDB的簡易入門,體系的簡單化,又很符合geeks追求簡潔 的夠用的想法。couchDB的宣傳中說它“like a porn star”也是挺傳神的。所以我比較看好他的發展,看到1.0穩定版會是個什麼樣子吧,這注定是一個跟web聯繫緊密的數據庫。

我個人比較企盼它能在分佈式處理方面有更多的改進,還有就是服務的配置、查詢的效率,都是有待提高的。至於大數據量的處理,我不太難期待,因爲看來 它應該是個網站前臺的產品,而不太適合用於後臺的分析。

參考文檔

1、couchDB官方網站:http://couchdb.apache.org/

2、couchDB wiki:http://wiki.apache.org/couchdb/

3、couchDB上手指南:http://erlang-china.org/study/couchdb-guide.html

 

----------------------------------------------------------------------------------------------------------------------

文章原文:   http://blog.nosqlfan.com/html/2754.html
  redis和 couchdb 本身職責就不同。所以兩個之間比較意義不大,記各自的優缺點即可。


相比來看,CouchDB 的長處正是Redis的短處:存儲大量的不易變但會被經常查詢的數據。Redis的長處正是CouchDB的短處:存儲小量的常變數據。


以一個博客系統爲例,CouchDB作爲一個文檔型數據庫,可以用來存儲文章,評論,模板及附件等,而Redis以其豐富的數據類型的數據結構,更適合用來存儲評論列表,網站實時狀態,過濾spam,用戶session信息以及頁面緩存。


作爲一個內存數據庫,Redis提供了快速對其數據結構進行復雜操作的功能,另外通過一份順序的日誌來保證其數據可靠性。
CouchDB使用了一種append-only的數據模型,不僅在數據庫數據存儲上,包括其B-tree和R-tree索引都是append-only的,所以如果你的數據修改操作太多(比如計數器應用),那麼CouchDB的數據文件會飛速膨脹。


Redis採用定時將內存數據Flush成RDB文件的方法來實現數據的持久化,而CouchDB的數據需要定時做數據壓縮以縮減數據文件的大小,這一過程會把數據文件讀入,壓縮後再寫成新的文件。是一個非常耗時的過程。


Redis提供了簡單的索引機制和複雜的數據結構,而CouchDB提供的是複雜的索引和簡單的數據結構。Redis適合用來存儲實時數據,而CouchDB適合用來存儲大量的文檔型數據。
下面是一個更詳細的各方面對比表格:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章