MongoDB管理:如何优雅的重启复制集?

啊!你还不了解MongoDB复制集?先看这里科普一下

复制集的成员启动后,会选举出一个Primary,Primary需要得到大多数成员的投票。所有的写入操作都必须向Primary发起,通过oplog将写操作同步到Secondary。

在复制集运行的过程中,难免会遇到需要重启节点的场景,比如复制集版本升级、节点维护等,在重启节点的过程中,建议不要直接shutdown Primary,这样可能导致已经写入primary但未同步到secondary的数据丢失,过程类似如下:

  1. shutdown Primary (shutdown会等待Secondary oplog追到10s以内)
  2. Primary退出后,剩余的节点选举出一个新的Primary(复制集只包含1或2节点例外)
  3. Primary重新启动,因为当前复制集已经有了新的Primary,这个Primary将以Secondary的角色运行。
  4. 从新的Primary同步的过程中,发现自己有无效的oplog,会先进行rollback。(rollback的数据只要不超过300M是可以找回的)

如果想不丢数据重启复制集,更优雅的打开方式应该是这样的

  1. 逐个重启复制集里所有的Secondary节点
  2. 对Primary发送stepDown命令,等待primary降级为Secondary
  3. 重启降级后的Primary

注意:如果Secondary的同步一直追不上Primary,步骤2可能会失败,这时应该重试步骤2直到stepDown成功;步骤2也可以通过调用replSetReconfig命令,来调整节点优先级来实现,让Secondary拥有更高的优先级,然后等待Primary降级为Secondary。

从上述分析可以看出,复制集里Primary、Secondary节点角色切换是很正常的事情,所以连接复制集一定不要直连Primary,否则在节点角色切换时不能正确容错,服务高可用无法保证。

另外,要想保证数据的高可靠,除了在运维上加强,在开发层面也可以做些工作,比如重要的数据写入通过WriteConcern: {w: “majority”}
来保证写入到大多数节点才向客户端确认。

参考资料

作者简介

张友东,阿里巴巴技术专家,主要关注分布式存储、Nosql数据库等技术领域,先后参与TFS(淘宝分布式文件系统)AliCloudDB for Redis等项目,目前主要从事AlidCloud For MongoDB的研发工作,致力于让开发者用上最好的MongoDB云服务。

发表评论