如果配置的实例已关闭,如何联系复制副本集



让我们假设我们有:

  • 1个副本集,具有2个数据实例(rs0_0和rs0_1)和一个仲裁器实例(rs0 _2)
  • 3个配置服务器实例(cfg0、cfg1和cfg2)
  • 1个mongos实例(mos0)

在所有实例(rs0_0、rs0_1、rs0-0、cfg0、cfg1、cfg2、mos0)启动后,我们配置副本集:

mongo rs0_0_host:rs0_0_port
    rs.initiate()
    cfg = rs.conf()
    cfg.members[0].priority = 100              (rs0_0 will be the primary if alive)
    rs.reconfig(cfg)
    rs.add("rs0_1_host:rs0_1_port")
    rs.addArb("rs0_2_host:rs0_2_port")         (arbiter)

然后我们将副本集(作为碎片)添加到集群中:

mongo mos0_host:mos0_port
    use admin
    db.runCommand({ addShard: "rs0/rs0_0_host:rs0_0_port", maxSize: 400000, name: "shard_rs0" })

现在让我们假设整个集群(所有实例)都关闭了,然后除了rs0_0之外的所有实例都启动了。副本集(碎片)是如何联系的?

我的意思是:我的应用程序(或mongo shell)连接到mos0,mos0要求配置服务器(cfg0、cfg1和/或cfg2),配置服务器从其配置中返回"rs0/rs0_host:rs0_port"(由于我们运行了"addShard"命令),然后mos0尝试连接到"rs0_hhost:rs0_port",但它不能,因为rs0_0已关闭。那么,mos0是如何知道rs0_1和rs0_2(活动的副本集实例)的存在的呢?

当然,我们可以这样配置碎片:

    db.runCommand({ addShard: "rs0/rs0_0_host:rs0_0_port,rs0_1_host:rs0_1_port,rs0_2_host:rs0_2_port", maxSize: 400000, name: "shard_rs0" })

通过这种方式,mos0将从配置服务器接收副本集实例的完整列表。但是,自MongoDB 2.0.3以来,只需要在"addShard"命令中指定一个实例(副本集)。那么诀窍在哪里呢?

在这种情况下,mongos将在内存中保存relpica集的内部映射,该内存每隔一段时间就会刷新一次(就像驱动程序一样),当成员开始联机时,它将进行一些检查,以及不应检测应联系的成员。当然,在初选之前,它不能写信给会员。

如果重新启动mongos并且配置的成员处于脱机状态,那么种子列表是很好的,此时mongos可以将另一个成员作为种子。