MongoDB Replica Set

一个replica set可以看作一个带故障转移的Master-Slave复制集群,它在primary节点失效后(或者secondaries不能访问primary时)会自动选举secondary节点成为master。replica set需要保证实例之间相互了解生存状态,所以需要n*(n-1)*2条心跳检测链路。在集群有一定规模时增加了网络的负担。如果使用开发语言的Driver指定了replica set中的一些server,那么driver会自动引入replica set中所有的server并自动在primary失效后故障转移到其他节点。

Replica Set Members

Replica set最多可以有12个成员,但是只有7个成员能同时投票。成员的角色分为:
Primary 同master节点,可以执行write操作。
Secondary 同Slave节点,接收并复制Primary节点的操作。可以进行一些其他配置:如设置为Non-Voting或优先级
Arbiter 不进行数据复制,只在primary失效后参与投票。

Replica Set Elections

Replica Set使用election(选举)来产生新的primary,该过程在初始化replica set和primary失效(或者secondaries不能访问primary)自动进行。
心跳:Replica Set成员每两秒发送心跳(ping)一次。如果某个成员在10秒内没有返回,那么其他成员则将该节点标记为不可访问。
优先级:priority 0时不能称为primary,priority越大越优先成为primary。默认优先级为1,下面命令显示优先级:
rs.conf()
primary step down: 接收到replSetStepDown命令,一个合格的secondary拥有更高的priority或者primary不能连接到replica set中的大多数成员。也就是说,更高优先级的设置会导致step down,从而重新选举新的priority。
Optime:成员最后一次应用日志操作的时间戳,一个replica set成员必须在可见成员里拥有最高的optime才能称为primary。
连通性:成为primary的节点必须能连到replica set中的大多数投票成员。例如,在一个三节点的集群中,有primary和其中一个secondary失效。那么剩余的成员继续保留secondary角色。如果两个secondary失效或者primary不能连到两个secondary,那么该primary则step down成为secondary;如果这两个secondary也互相不能访问,那么将不会产生primary。

Initializing a set

在初始化一个replica set之前,最好使用ntp同步一下时间。创建一个replica set需要使用新的选项--replSet来启动mongod,该选项后面为replica set的名字和它的其他成员节点(可以是还未启动的)。

此时日志中会提示连接失败

ubt1的日志中出现:

#同理启动ubt3成员mongod。日志中提示虽然连接成功,但是没有初始化。下面进行初始化。

members可以有其他字段,例如priority或arbiterOnly。等待sync完成后,在secondary上设置 “slave okay” 模式通知mongo shell你允许从一个secondary上读取数据。登录ubt3

由此可见,primary的数据复制成功。

Failover test

首先检查一下当前复制状态,保证optime的时间戳一致。

然后毫不留情的干掉primary(killall mongod),登录ubt2可以看出,该成员已经被选举为primary

OK,然后重启ubt1上的成员。ubt2(primary)的日志提示:
2014-06-12T16:14:04.104+0800 [rsHealthPoll] replSet member ubt1:27017 is up
2014-06-12T16:14:04.104+0800 [rsHealthPoll] replSet member ubt1:27017 is now in state SECONDARY

Secondary with higher priority

下面测试一下当一个secondary的priority大于primary后的行为。当前ubt2为primary,三个成员的priority都为默认的1,将ubt1的priority设置为2。reconf的操作需要在primary上进行。

日志输出如下,我们可以看出,这个replica进行了一次新的选举,ubt1成为了新的primary。

Done~
^^
Reference:
《MongoDB – The Definitive Guide》
MongoDB Docs

Posted in Database, JavaScript, NoSQL.