在mongodb 3.0复制中,当辅助设备发生故障时选举将如何发生

时间:2015-11-29 07:02:56

标签: mongodb database-replication wiredtiger

情况:我在两台计算机上设置了MongoDB复制。

  • 一台计算机是保存主节点和仲裁服务器的服务器。此服务器是实时服务器,始终打开。它在复制中使用的本地IP是192.168.0.4
  • 其次是辅助节点所在的PC,每天开启几个小时。它在复制中使用的本地IP是192.168.0.5

我的期望:我希望实时服务器成为我的应用程序数据交互的主要点,无论PC的状态如何(无论是否可访问,因为PC是次要的) ,所以我想确保服务器的节点始终是主节点。

以下是rs.config()

的结果
liveSet:PRIMARY> rs.config()
{
    "_id" : "liveSet",
    "version" : 2,
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.0.4:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 10,
            "tags" : {

            },
            "slaveDelay" : 0,
            "votes" : 1
        },
        {
            "_id" : 1,
            "host" : "192.168.0.5:5051",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {

            },
            "slaveDelay" : 0,
            "votes" : 1
        },
        {
            "_id" : 2,
            "host" : "192.168.0.4:5052",
            "arbiterOnly" : true,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {

            },
            "slaveDelay" : 0,
            "votes" : 1
        }
    ],
    "settings" : {
        "chainingAllowed" : true,
        "heartbeatTimeoutSecs" : 10,
        "getLastErrorModes" : {

        },
        "getLastErrorDefaults" : {
            "w" : 1,
            "wtimeout" : 0
        }
    }
}

此外,如果重要的话,我已将存储引擎设置为WiredTiger。

我实际得到了什么,以及问题:当我关闭电脑或杀死它的mongod进程时,服务器上的节点就成了次要的。

以下是当我连接到主节点的shell时杀死PC的mongod进程时服务器的输出:

liveSet:PRIMARY>
2015-11-29T10:46:29.471+0430 I NETWORK  Socket recv() errno:10053 An established connection was aborted by the software in your host machine. 127.0.0.1:27017
2015-11-29T10:46:29.473+0430 I NETWORK  SocketException: remote: 127.0.0.1:27017 error: 9001 socket exception [RECV_ERROR] server [127.0.0.1:27017]
2015-11-29T10:46:29.475+0430 I NETWORK  DBClientCursor::init call() failed
2015-11-29T10:46:29.479+0430 I NETWORK  trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2015-11-29T10:46:29.481+0430 I NETWORK  reconnect 127.0.0.1:27017 (127.0.0.1) ok
liveSet:SECONDARY>

<小时/> 对我来说有两个疑问:

  1. 考虑this part of MongoDB documentation
  2.   

    副本集使用选举来确定哪个集合成员将成为主要成员。在启动副本集之后以及主节点变为不可用时也会发生选举。

    选举发生在主要人物不可用时(或在启动时,但这部分与我们的情况无关),但主要部分始终可用,所以为什么选举会发生。

    1. 考虑相同文档的这一部分:
    2.   

      如果大多数副本集不可访问或不可用,则副本集不能接受写入,并且所有剩余成员都变为只读。

      考虑到部分'成员变为只读',我有两个节点而不是一个节点,所以这不应该影响我们的复制。

      现在我的问题:当PC上的节点无法访问时,如何将服务器上的节点保留为主节点?

      更新 这是rs.status()的输出。

      感谢Wan Bachtiar,现在这使得行为显而易见,因为仲裁者无法到达。

      liveSet:PRIMARY> rs.status()
      {
          "set" : "liveSet",
          "date" : ISODate("2015-11-30T04:33:03.864Z"),
          "myState" : 1,
          "members" : [
              {
                  "_id" : 0,
                  "name" : "192.168.0.4:27017",
                  "health" : 1,
                  "state" : 1,
                  "stateStr" : "PRIMARY",
                  "uptime" : 1807553,
                  "optime" : Timestamp(1448796026, 1),
                  "optimeDate" : ISODate("2015-11-29T11:20:26Z"),
                  "electionTime" : Timestamp(1448857488, 1),
                  "electionDate" : ISODate("2015-11-30T04:24:48Z"),
                  "configVersion" : 2,
                  "self" : true
              },
              {
                  "_id" : 1,
                  "name" : "192.168.0.5:5051",
                  "health" : 1,
                  "state" : 2,
                  "stateStr" : "SECONDARY",
                  "uptime" : 496,
                  "optime" : Timestamp(1448796026, 1),
                  "optimeDate" : ISODate("2015-11-29T11:20:26Z"),
                  "lastHeartbeat" : ISODate("2015-11-30T04:33:03.708Z"),
                  "lastHeartbeatRecv" : ISODate("2015-11-30T04:33:02.451Z"),
                  "pingMs" : 1,
                  "configVersion" : 2
              },
              {
                  "_id" : 2,
                  "name" : "192.168.0.4:5052",
                  "health" : 0,
                  "state" : 8,
                  "stateStr" : "(not reachable/healthy)",
                  "uptime" : 0,
                  "lastHeartbeat" : ISODate("2015-11-30T04:33:00.008Z"),
                  "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
                  "configVersion" : -1
              }
          ],
          "ok" : 1
      }
      liveSet:PRIMARY>
      

1 个答案:

答案 0 :(得分:2)

如文档中所述,如果大多数副本集不可访问或不可用,则副本集不能接受写入,并且所有剩余成员都变为只读。

在这种情况下,如果无法访问仲裁服务器和辅助服务器,则必须降级主服务器。 rs.status()应该能够确定副本成员的健康状况。

您应该注意的一件事是主oplog size。 oplog的大小决定了副本集成员可以关闭的时间长度,并且当它重新联机时仍能够赶上。 oplog大小越大,处理成员的时间就越长,因为oplog可以容纳更多操作。如果确实落后太多,则必须通过删除其数据文件并执行initial sync来重新同步该成员。

有关详细信息,请参阅Check the size of the Oplog

问候,

万。