BigCouch架構
CHTTPD
封裝了FABIC介面,CouchDB在HTTP層的叢集操作
FABRIC
CouchDB叢集的操作代理。
主要用於控制CouchDB叢集,Erlang層面的操作
REXI
Rexi是傳送CouchDB的操作節點叢集中的一個特製的RPC伺服器應用程式。
MEM3
CouchDB叢集的節點新增程式,在BigCouch中使用主要用於跟蹤叢集的兩個重要資訊:
成員節點資訊;
每個資料庫節點(分割槽)的對映關係;
節點資訊和分割槽資訊在本地節點資料庫中進行跟蹤。
拆分與合併分割槽在尚未成熟。
BigCouch資料庫引數
Q引數
在建立資料庫時指定資料庫的分割槽數量(一致性雜湊分割槽數)。
可能存在多個分割槽在同一節點上,允許你在叢集的節點數量增長而無需re-shard操作。
預設值是8,可以在配置檔案中進行更改:
在default.ini檔案中cluster區域的q欄位;
也可以在建立資料庫時指定,比如:
curl -X PUT http://172.16.10.2:5984/test_db?q=4&n=3
分割槽示意圖:
Q = 4時可以將資料庫分為4個分割槽
假設有5個節點,這4個分割槽會分佈在5個節點上,示例如下:
N引數
每個分片的冗餘拷貝數量。
預設值是3,可以在配置檔案中進行更改:
在default.ini檔案中cluster區域的n欄位;
也可以在建立資料庫時指定,比如:
curl -X PUT http://172.16.10.2:5984/test_db?q=4&n=3
假設N=3,節點數為5個,每個分割槽將會複製3份並按一定的演算法分片到5個節點上,分割槽中的文件會複製3份同步到每一個備份分割槽,示例如下:
BigCouch節點刪除
需要刪除的節點A,檔案備份節點B
資料遷移
將A節點上 var/lib/shards/ 目錄下的.couch檔案通過scp等方式複製到B節點相同目錄裡;
資料同步
複製後如果A節點的資料有更新,在5986埠執行同步操作;
通知BigCouch叢集新檔案地址
在dbs資料庫裡面更新資料庫配置文件,內容示例:
{
"_id": "test_db",
"_rev": "2-45088d2d1bb389c3fced1a952c2ea124",
"by_node": {
"bigcouch@172.16.10.2": [
"00000000-3fffffff",
"80000000-bfffffff"
],
"bigcouch@172.16.10.3": [
"40000000-7fffffff",
"c0000000-ffffffff"
],
"bigcouch@172.16.10.5": [
"40000000-7fffffff",
"c0000000-ffffffff",
"00000000-3fffffff",
"80000000-bfffffff"
],
"bigcouch@172.16.10.6": [
"40000000-7fffffff",
"c0000000-ffffffff"
],
"bigcouch@localhost.localdomain": [
"00000000-3fffffff",
"80000000-bfffffff"
]
},
"by_range": {
"00000000-3fffffff": [
"bigcouch@172.16.10.2",
"bigcouch@172.16.10.5",
"bigcouch@localhost.localdomain"
],
"40000000-7fffffff": [
"bigcouch@172.16.10.3",
"bigcouch@172.16.10.5",
"bigcouch@172.16.10.6"
],
"80000000-bfffffff": [
"bigcouch@172.16.10.2",
"bigcouch@172.16.10.5",
"bigcouch@localhost.localdomain"
],
"c0000000-ffffffff": [
"bigcouch@172.16.10.3",
"bigcouch@172.16.10.5",
"bigcouch@172.16.10.6"
]
}
}
修改by_node和by_range欄位,將A相關的資訊修改為B的。
斷開A伺服器與叢集的連線
修改set-cookie值並重啟BigCouch伺服器
移除叢集A節點
通過叢集5986埠訪問nodes資料庫,刪除A伺服器相關文件
刪除A伺服器上的nodes資訊和dbs資訊
清理shards目錄中的檔案,重啟A伺服器的BigCouch
5節點環境中,節點與叢集斷開時,該節點不可用。
衝突管理
衝突處理的例子
環境介紹
叢集中三個節點:
A : 172.16.10.2
B : 172.16.10.3
C : 172.16.10.5
資料庫:test_db
Q = 1,N=3
資料庫不分割槽,備份三份。
新增資料:
{
"
_id
":
"2809580fa3dc3d8d719c02c229000518"
,
"
_rev
":
"1-1bd878534def1c2c9224e7398ab6a987"
,
"
name
":
"beforeChange"
}
製造衝突
1、關閉B和C伺服器;
2、修改A伺服器的資料
{
"
_id
":
"2809580fa3dc3d8d719c02c229000518"
,
"
_rev
":
"2-6de54d127839d323b743435f447cb29f"
,
"
name
":
"mike"
}
3、關閉A伺服器;
4、在A伺服器關閉後,啟動B伺服器;
5、修改B伺服器的資料
{
"
_id
":
"2809580fa3dc3d8d719c02c229000518"
,
"
_rev
":
"2-19f995ede86cd2c367b2d90568a6f8c6"
,
"
name
":
"MIKE"
}
6、啟動A伺服器;
驗證資料
B伺服器已同步為A的資料
2、C伺服器資料也同步為A的資料
衝突檢測
衝突檢查函式:
function(doc){
if(doc._conflicts){
emit(doc._conflicts,null);
}
}
文件中的doc._conflicts屬性是一個陣列,列出了所有的衝突修訂。
處理衝突
couchDB通過一個演算法來選出勝利的修訂,解決衝突。應用程式不應該信賴於這個演算法,而是應該先去解決衝突。
自動衝突處理
每一個修訂都包含有一個先前修訂的列表,那個擁有最長的修訂歷史的修訂會最終成為勝出的修訂;如果兩個修訂歷史剛好一樣長,那麼會比較它們的_rev值的ASCII序列,ASCII值更大的那個會最終勝出。所以在上面的例子中,2-6de54d127839d323b743435f447cb29f勝出了,2-19f995ede86cd2c367b2d90568a6f8c6落選了。
手動衝突處理
首先,用想要的值在目標文件上進行重寫,然後把不想要的修訂刪除就可以了。
具體如下:
1、 讀取當前文件;
2、 讀取舊(衝突)版本;
3、 應用特定於域的合併邏輯;
4、 將文件更新為新(合併)版本;
5、 移除衝突文件版本。
本文github地址:
https://github.com/mike-zhang/mikeBlogEssays/blob/master/2014/20141007_bigCouch資料整理.md
歡迎補充