一边搭建一边理解MongoDB副本集(副本集协议版本)
MongoDB提供了副本集协议0(pv0)和副本集协议1(pv1):
- pv0降低了使用写关注w:1回滚的可能性。但是,pv0导致在某些网络分区情况下写关注w:”majority”的确认丢失。
- pv1 保证了写关注w:”majority”的确认不会丢失。然而pv1默认优先于更快的故障转移,而不是保留w:1写入,但是可以配置为以较慢的故障转移时间为代价优先保留大多数w:1写入。
NOTE
pv1在MongoDB 3.2之后,是新创建副本集的默认协议。
下面列出了pv0和pv1的一些不同点。
可用
- pv0在所有MongoDB版本下可用。
- pv1在MongoDB 3.2版本之后可用,并且是新创建副本集的默认协议。
写关注
写关注 | pv0 | pv1 |
---|---|---|
“local” | ✓ | ✓ |
“majority” | ✓ | |
“linearizable” | ✓ | ✓ |
监督者
对于有监督者的副本集,pv1相对于pv0增加了写关注w:1发生回滚的可能性。
投票
pv0基于成员的optime和properity来允许成员一票否决投票。
pv1不使用否决。单个成员可以在特定选举投票赞成或反对选举人,但不能一票否决(终止)选举。
检测存在多个主节点
在一些情况下,两个副本集中的阶段会短暂的都认为自己是主节点,但是,其中一个才有能力完成{w:”majority”}写操作的写关注。可以完成{w:”majority”}写操作的写关注的节点才是当前的主节点,另一个是通常因为网络分区,还未意识到需要退位的先前的主节点。当这种情况发生了,连接到先前主节点的客户端可能观察到过期的数据,尽管设置了有限读取主节点选项,并且对先前主节点的写入最终会被回滚。
pv0依靠时钟同步来消除两个成员都认为自己是主节点的情况。 依赖时钟同步可导致w:majority写关注的确认丢失。
为了替代时钟同步,pv1使用了术语terms(一个单调递增的选举计数器)。这样就能在短时间内多次成功的选举时检测同时存在的主节点。pv0会带导致在短时间内需要进行多次选举时副本集没有主节点。
连续的选举
为了最大化写可用,pv1在选举时不考虑priority。相反,如果副本集已经有了一个稳定的主节点,pv1会尽最大努力让拥有最大优先级的从节点发起选举。这可能导致连续的选举因为更高优先级得合适成员会发起选举。但不像pv0在连续选举中有三十秒缓冲,在pv1中使用terms允许更快的连续选举出现。
增加了选举频繁性和选举中间没有缓冲时间,pv1增加了回滚w:1写操作的可能性。但是,你可以通过增加catchUpTimeoutMillies设置来减少回滚的数量、
在选举中,pv0允许节点基于priority来一票否决。例如,在副本集拥有稳定主节点后,pv0相比pv1减少了连续选举的次数。因为pv0依赖时钟同步来检测多个主节点,pv0包含了在连续选举间30秒缓冲时间来保护时钟同步。
二次投票
pv1使用了terms来防止在一次选举中投两次票的情况。
pv0通过30秒缓冲时间减少了两次投票的可能性,但是这不能保证如果选举超过了30秒,成员不会投两次票。
总结
pv0 | pv1 | |
---|---|---|
w: 1 写 | 优先保存 | 增加了回滚w:1写操作的可能性,可通过catchUpTimeoutMillies设置调整 |
w: “majority”写 | 可能丢失w: “majority”写确认 | 保证不丢失”majority”写确认 |
没有主节点 | 更有可能 | 不太可能 |
一票否决 | 支持 | 不需要 |
连续选举 | 不频繁,30秒缓冲 | 更可能发生,没有缓冲 |
监督者 | 不太可能丢失w:1写操作 | 更可能丢失w:1写操作 |