副本集是对主从复制的一种完善,也是推荐的MongoDB复制策略。我们会从配置的一个示例副本集开始,然后描述复制是如何工作的,这些知识对于诊断线上问题是极为重要的。最小的推荐副本集配置由三个节点组成。其中两个节点时一等的、持久化mongod实例,两者都能作为副本集的主节点,都有完整的数据副本。集合里的第三个节点时仲裁节点,不复制数据,只是中立观察者。仲裁节点是进行仲裁的:在要求故障转移时,仲裁节点会帮助选出新的主节点。下图描述了要配置的副本集。
1. 创建副本集
在Windows环境下创建1个主节点,一个从节点一个仲裁节点的副本集,具体的创建步骤,请参考我的相应博文点击打开链接。若你为设置对应的副本集设置,也可以在当前的mongo连接中使用rs.initiate(),启动一个只有单节点的副本集;后续可以使用rs.add(host)将新的host增加到副本集中。在添加仲裁节点时,请将对应节点的arbiterOnly属性设置为true,否则为普通的从节点。
2. 查看相应节点状态
db.isMaster()
执行rs.status()
除非你的MongoDB数据库里包含很多数据,否则副本集应该能在30s内上线。在此期间,每个节点的stateStr字段应该会从RECOVERING变为PRIMARY、SECONDARY或ARBITER。
3. 检测副本集运作
当前副本集已经开始运作了,你可能希望看到一些证据。因此在主节点中插入一个文档:
mongo -port 27111
use bookstore
db.books.insert({title:"Oliver Twist"})
然后在从节点上,查询数据是否已经异步复制过来了。但是此时在从节点上运行show dbs时,出现下图报错。
通过报错提示,这个节点不是主节点,或者从节点的状态没有OK,这时在从节点上执行下rs.salveOk(),执行完上述代码后,再次运行show dbs,执行正常,结果如下图。
如果上述的你能看到上述的显示结果,那么证明你的复制已经正常运作了,说明成功地配置了副本集。
4. 测试副本集主从节点切换方式
能实实在在地看到复制让人觉得很满意,但也许自动故障转移会更有趣一些。我们使用杀掉一个节点的方法,如果杀掉了从节点,只会停止复制,剩余的节点仍然会保持当前的状态。如果希望状态发生变化,就需要杀掉主节点。通过ctrl+C或者kill -2,或者连接上主节点后执行db.shutdownServer()
一旦杀掉了主节点,从节点就会检测不到心跳了,随后会把自己选举为主节点。这样的选举时可行的,因为原始节点中的大多数节点(仲裁节点和原始的从节点)仍能ping到对方。从下面的执行结果发现,主节点被杀掉后,原始从节点被选举为主节点,原始的主节点变为不可到达。
故障转移后,副本集中只有两个节点了。因为仲裁节点没有数据,只要应用程序和主节点通信,它就能继续运作。即便如此,复制停止了,现在就不能再做故障转移了。老的主节点必须恢复。假设它是正常关闭的,可以让它再度上线,它会自动以从节点的身份重新加入副本集。重新老的主节点后,再次查询状态结果如下: