文章目錄
- 簡介
- 優點:
- 技術概述:
- 資料格式:
- 緩衝:
- 更新機制(如何保持資料一致性):
- 分布式:
- 穩定性:
- python用戶端:
- couchDB要做什麼(它的能與不能):
- 前景:
- 參考文檔
http://www.wentrue.net/blog/?p=255
簡介
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一樣需要掃全表,但可以對常用的一些查詢建立永久索引,索引是隨資料的增長累加式更新的,減少查詢時間。
當然,強大的mysql也有類似的解決方案,且看friendfeed的schema-less 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