今天有同事问我,副本集两个节点怎么做高可用,我也很好奇两个节点用副本集的方式怎么做高可用?查了一些资料,发现至少要三个节点才能做,也算是给自己普及理论知识。


选举算法

mongodb副本集的选举机制采用bully算法,bully算法是一种相对简单的协调者竞选算法,mongodb用这个算法来选举副本集中的主节点。bully算法主要思想是集群中的每个成员都可以声明它是主节点(协调者)并通知其他节点,别的节点可以选择接受这个声称或是拒绝并进入协调者竞争,被其他所有节点接受的节点才能成为协调者,节点按照一些属性来判断谁应该胜出,这个属性可以是一个静态ID,也可以是更新的度量像最近一次事务ID(最新的节点会胜出)。

这个网站有个bully算法例子,挺不错的http://blog.nosqlfan.com/html/4139.html

下图的例子展示了bully算法的执行过程。使用静态ID作为度量,ID值更大的节点会胜出:

  1. 最初集群有5个节点,节点5是一个公认的协调者。

  2. 假设节点5挂了,并且节点2和节点3同时发现了这一情况。两个节点开始竞选并发送竞选消息给ID更大的节点。

  3. 节点4淘汰了节点2和3,节点3淘汰了节点2。

  4. 这时候节点1察觉了节点5失效并向所有ID更大的节点发送了竞选信息。

  5. 节点2、3和4都淘汰了节点1。

  6. 节点4发送竞选信息给节点5。

  7. 节点5没有响应,所以节点4宣布自己当选并向其他节点通告了这一消息。

Mongodb集群 - 副本集内部选举机制_mongodb  repset

这是某位大神画的图,看得真直观。我也尝试用word来画,画图果然是个细活啊!


协调者竞选前提条件:集群中有一半以上的节点参与了竞选。这确保了在网络隔离的情况下只有一部分节点能选出协调者(假设网络中网络会被分割成多块区域,之间互不联通,协调者竞选的结果必然会在节点数相对比较多的那个区域中选出协调者,当然前提是那个区域中的可用节点多于集群原有节点数的半数。如果集群被隔离成几个区块,而没有一个区块的节点数多于原有节点总数的一半,那就无法选举出协调者,当然这样的情况下也别指望集群能够继续提供服务了)。


选举触发条件

1  初始化一个副本集时

2  主节点和副本集断开连接(可能是网络问题)

3  主节点宕机


MongoDB集群配置

参考官方:https://docs.mongodb.org/manual/tutorial/deploy-replica-set/

                  https://docs.mongodb.org/manual/tutorial/adjust-replica-set-member-priority/ (动态调整副本集成员priority)



参考链接

http://www.lanceyan.com/tech/mongodb_repset2.html