BigCouch资料整理

 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

欢迎补充

posted on 2014-10-09 20:58  Mike_Zhang  阅读(1637)  评论(0编辑  收藏  举报