研磨CouchDB-技術概述

1.文檔存儲數據庫

一個承載着CouchDB服務器主機的數據庫,以文檔方式存儲。每一個文檔在數據庫中都有惟一的名稱,CouchDB提供一個RESTful HTTP API來讀取和更新(添加、編輯、刪除)數據庫文檔。編程

文檔是CouchDB中的主要數據單元,由任意數量的字段和附件組成。文檔還包括數據庫系統維護的元數據。文檔字段是惟一命名的,而且包含不一樣類型的值(文本、數字、布爾值、列表等),而且沒有對文本大小或元素數量的設置限制。安全

CouchDB文檔更新模型是無鎖且樂觀的。文檔編輯是經過客戶機應用程序加載文檔、應用更改並將它們保存回數據庫來完成的。若是另外一個編輯相同文檔的客戶端首先保存其更改,則客戶端在保存時將得到編輯衝突錯誤。要解決更新衝突,能夠打開最新的文檔版本,從新應用編輯並再次嘗試更新。服務器

單個文檔更新(添加、編輯、刪除)要麼所有更新,要麼什麼也不更新, 文檔更新要麼徹底成功,要麼徹底失敗。數據庫從不包含部分保存或部編輯的文檔。網絡

2. 原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability) 併發

CouchDB文件被設計爲可以保證系統具備全部原子性、一致性、隔離性、持久性(ACID)屬性。在磁盤上,CouchDB從不覆蓋提交的數據或相關結構,確保數據庫文件始終處於一致的狀態。這是一種「僅崩潰」的設計,CouchDB服務器不會經歷關閉過程,而是簡單地終止。編程語言

文檔更新(添加、編輯、刪除)是序列化的,但併發寫的二進制 除外。數據庫讀取永遠不會被鎖住,也永遠沒必要等待寫入或其餘讀取者。任何數量的客戶端均可以在不被鎖定或被併發更新中斷的狀況下讀取文檔,即便是在同一文檔上。(我的理解這裏多是髒讀的形式)CouchDB讀取操做使用多版本併發控制(MVCC)模型,其中每一個客戶端從讀取操做的開始到結束均可以看到數據庫的一致快照。這意味着CouchDB能夠在每一個文檔的基礎上保證事務語義。分佈式

文檔經過它們的名稱(文檔ID)和序列ID在B-tree樹中創建索引。對數據庫實例的每次更新都會生成一個新的序列號。序列id稍後用於增量地查找數據庫中的更改。當保存或刪除文檔時,這些B-tree索引將同時更新。索引更新老是發生在文件的末尾(僅追加更新)。函數

文檔的優點在於,數據已經被方便地打包用於存儲,而不是在大多數數據庫系統中分散到多個表和行中。當文檔被提交到磁盤時,文檔字段和元數據被打包到緩衝區中,一個文檔接着一個文檔(有助於之後高效地構建視圖)。佈局

更新CouchDB文檔時,全部數據和相關索引都被刷新到磁盤,事務提交老是使數據庫處於徹底一致的狀態。提交分兩步進行:

  1. 全部文檔數據和相關索引更新都同步刷新到磁盤。
  2. 更新後的數據庫頭由兩個連續的、相同的塊組成,組成文件的第一個4k,而後同步地刷新到磁盤。

在第1步操做系統崩潰或電源故障的狀況下,從新啓動時只會忘記部分刷新的更新。若是在第2步(提交頭文件)中發生這樣的崩潰,將保留先前相同頭文件的存活副本,以確保先前提交的全部數據的一致性。除了頭部區域外,沒有必要在崩潰或電源故障後進行一致性檢查或修復。

3.壓縮

偶爾的壓縮能夠回收被浪費的空間。按照計劃,或者當數據庫文件超過必定數量的浪費空間時,壓縮過程將全部活動數據克隆到一個新文件中,而後丟棄舊文件。數據庫始終保持在線狀態,全部更新和讀取均可以成功完成。只有在複製了全部數據並將全部用戶轉移到新文件時,纔會刪除舊數據庫文件。

我的感受,這裏應該使用了不少技術來保障一致性,若是是在拷貝過程當中文檔進行了更新,官方文檔沒有給出來具體的解決方案。

4. 視圖

ACID屬性只處理存儲和更新,可是咱們還須要可以以有趣和有用的方式顯示數據。與必須當心地將數據分解爲表的SQL數據庫不一樣,CouchDB中的數據存儲在半結構化文檔中。CouchDB文檔是靈活的,每一個文檔都有本身的隱式結構,這減輕了雙向複製表模式及其包含的數據的最困難的問題和陷阱。

可是,除了充當一個奇特的文件服務器以外,用於數據存儲和共享的簡單文檔模型對於構建真正的應用程序來講過於簡單——它不能完成咱們想要和指望的足夠多的事情。咱們但願經過許多不一樣的方式來切分和查看咱們的數據。如今須要的是一種方法來過濾、組織和報告還沒有分解爲表的數據。

4.1 視圖模式

爲了解決將結構添加回非結構化和半結構化數據的問題,CouchDB集成了一個視圖模型。視圖是將文檔聚合和造成數據庫報表的方法,是按需構建的,用於聚合、鏈接和造成數據庫報表文檔。由於視圖是動態構建的,而且不影響底層文檔,因此您能夠擁有相同數據的任意多個不一樣視圖表示。

視圖定義嚴格來講是虛擬的,只顯示當前數據庫實例中的文檔,使它們與所顯示的數據分離,並與複製兼容。CouchDB視圖是在特殊的設計文檔中定義的,能夠像常規文檔同樣跨數據庫實例進行復制,這樣不只能夠在CouchDB中複製數據,還能夠複製整個應用程序設計。

4.2 JavaScript視圖功能

圖是使用JavaScript函數定義的,這些函數在map-reduce系統中充當映射部分。視圖函數接受CouchDB文檔做爲參數,而後執行所需的任何計算,以肯定將經過視圖提供的數據(若是有的話)。它能夠基於單個文檔向視圖添加多行,也能夠徹底不添加行。

4.3 View 索引

視圖是數據庫實際文檔內容的動態表示,CouchDB使建立有用的數據視圖變得很容易。可是,生成包含數十萬或數百萬文檔的數據庫視圖須要時間和資源,系統不該該每次都從頭開始。

爲了保持視圖查詢的速度,視圖引擎維護其視圖的索引,並增量地更新它們以反映數據庫中的更改。CouchDB的核心設計主要圍繞高效、增量地建立視圖及其索引進行優化。

視圖及其函數定義在特殊的「設計」文檔中,文檔中能夠包含任意數量的唯一命名的視圖函數。當用戶打開一個視圖並自動更新其索引時,同一設計文檔中的全部視圖都被索引爲單個組。

視圖生成器使用數據庫序列ID來肯定視圖組是否與數據庫徹底同步。若是沒有,視圖引擎將檢查自上次刷新以來更改的全部數據庫文檔(按打包順序排列)。文檔按在磁盤文件中出現的順序讀取,從而下降磁盤磁頭查找的頻率和成本。

視圖能夠在刷新的同時,同時讀取和查詢。若是客戶機正在緩慢地將大視圖的內容讀取出來,則能夠同時爲另外一個客戶機打開和刷新相同的視圖,而不會阻塞第一個客戶機。對於任何數量的併發客戶機閱讀器都是如此,它們能夠在爲其餘客戶機併發刷新索引時讀取和查詢視圖,而不會給閱讀器帶來問題。

當視圖引擎經過您的「map」和「reduce」函數處理文檔時,若是存在它們的前一行值,那麼它們將從視圖索引中刪除。若是文檔是由視圖函數選擇的,那麼函數結果將做爲新行插入視圖。

當將視圖索引更改寫入磁盤時,更新老是附加在文件末尾,這既能夠減小磁盤提交期間的磁頭查找時間,又能夠確保崩潰和電源故障不會致使索引損壞。若是在更新視圖索引時發生崩潰,則不完整的索引更新只會丟失,並從其先前提交的狀態增量地從新構建。

5.安全和校驗

爲了保護那些能夠閱讀和更新的文檔,CouchDB有一個簡單的閱讀器訪問和更新驗證模型,能夠擴展該模型來實現定製的安全模型。

5.1管理員訪問

CouchDB數據庫實例具備管理員賬戶。管理員賬戶能夠建立其餘管理員賬戶並更新設計文檔。設計文檔是包含視圖定義和其餘特殊公式的特殊文檔,以及常規字段和blob。

5.2 更新校驗

因爲文檔是寫到磁盤上的,所以能夠經過JavaScript函數動態地驗證它們,以實現安全性和數據驗證。當文檔經過全部公式驗證條件時,容許繼續更新。若是驗證失敗,更新將停止,用戶客戶機將得到錯誤響應。用戶憑證和更新後的文檔都做爲驗證公式的輸入,能夠經過驗證用戶更新文檔的權限來實現自定義安全模型。基本的author only update文檔模型實現起來很簡單,其中驗證文檔更新以檢查用戶是否列在現有文檔的author字段中。更動態的模型也是可能的,好比檢查一個單獨的用戶賬戶配置文件的權限設置。更新驗證對實時使用和複製的更新都是強制的,以確保共享、分佈式系統中的安全性和數據驗證。

6. 分佈式更新和複製

CouchDB是一個基於對等的分佈式數據庫系統。它允許用戶和服務器在斷開鏈接時訪問和更新相同的共享數據。而後能夠在之後雙向複製這些更改。CouchDB文檔存儲、視圖和安全模型被設計爲協同工做,以使真正的雙向複製高效可靠。文檔和設計均可以複製,從而容許將完整的數據庫應用程序(包括應用程序設計、邏輯和數據)複製到筆記本電腦上脫機使用,或者複製到遠程辦公室的服務器上,在遠程辦公室中,鏈接速度慢或不可靠會使共享數據變得困難。複製過程是增量的。在數據庫級別,複製只檢查自上次複製以來更新的文檔。若是複製在任何步驟失敗,例如因爲網絡問題或崩潰,下一個複製將在最後一個檢查點從新啓動。能夠建立和維護部分副本。複製能夠經過JavaScript函數進行過濾,以便只複製特定的文檔或知足特定條件的文檔。這容許用戶離線使用大型共享數據庫應用程序的子集,同時保持與應用程序和該數據子集的正常交互。

6.1 衝突

衝突檢測和管理是對任何分佈式文本編輯系統都是關鍵問題。CouchDB存儲系統將編輯衝突視爲一種常見狀態,而不是異常狀態。衝突處理模型簡單、無損,同時保留了單一的文檔語義,容許分散的衝突解決。

CouchDB容許數據庫中同時存在任意數量的衝突文檔,每一個數據庫實例決定哪一個文檔是贏家,哪一個文檔是衝突。只有獲勝的文檔才能出如今視圖中,而失敗的衝突仍然能夠訪問,並保留在數據庫中,直到在數據庫壓縮過程當中刪除或清除。由於衝突文檔仍然是常規文檔,因此它們像常規文檔同樣複製,而且遵循相同的安全性和驗證規則。

當分佈式編輯衝突發生時,每一個數據庫副本都看到相同的獲勝修訂,而且每一個副本都有機會解決衝突。解決衝突能夠手工完成,或者根據數據的性質和衝突由自動化代理完成。該系統在維護單個文檔數據庫語義的同時,使分散的衝突解決成爲可能。

即便多個斷開鏈接的用戶或代理試圖解決相同的衝突,衝突管理仍將繼續工做。若是解決的衝突致使更多的衝突,系統將以相同的方式容納它們,在每臺機器上肯定相同的贏家,並維護單個文檔語義。

6.2 應用程序

僅使用基本複製模型,許多傳統的單服務器數據庫應用程序幾乎不須要額外的工做就能夠實現分佈式。CouchDB複製被設計爲能夠當即用於基本的數據庫應用程序,同時還能夠擴展用於更復雜和功能更全面的用途。只需不多的數據庫工做,就能夠構建具備細粒度安全性和完整修訂歷史的分佈式文檔管理應用程序。能夠實現對文檔的更新來利用增量字段和blob複製,在增量字段和blob複製中,複製的更新幾乎與實際的編輯差別(diffs)同樣高效和增量。

7. 實施

CouchDB構建在Erlang OTP平臺上,這是一種功能強大的併發編程語言和開發平臺。Erlang是爲實時電信應用程序開發的,特別強調可靠性和可用性。

不管是在語法仍是語義上,Erlang都與C或Java等傳統編程語言很是不一樣。Erlang使用輕量級進程和消息傳遞實現併發,它沒有共享的狀態線程,全部數據都是不可變的。Erlang的健壯性和併發性很是適合數據庫服務器。

CouchDB在概念模型和實際的Erlang實現中是爲無鎖併發性設計的。減小瓶頸和避免鎖定可使整個系統在重負載下正常工做。CouchDB能夠容納許多客戶機,它們能夠複製更改、打開和更新文檔,以及查詢同時爲其餘客戶機刷新索引的視圖,而不須要鎖。

對於更高的可用性和更多的併發用戶,CouchDB是爲無共享集羣而設計的。在一個無共享的集羣中,每臺機器都是獨立的,並與集羣夥伴複製數據,從而容許各個服務器在零停機時間內發生故障。因爲在從新啓動時不須要一致性掃描和修復,若是因爲數據中心斷電致使整個集羣失敗,例如,從新啓動後整個CouchDB分佈式系統當即可用。

CouchDB從一開始就使用分佈式文檔數據庫系統的一致視圖構建。與將分佈式特性固定在相同的遺留模型和數據庫之上的繁瑣嘗試不一樣,它是通過仔細推敲的設計、工程和集成的結果。文檔、視圖、安全性和複製模型、特殊用途的查詢語言、高效而健壯的磁盤佈局以及Erlang平臺的併發性和可靠性,都被當心地集成爲一個可靠而高效的系統。

相關文章
相關標籤/搜索