在mongodb 3.0复制中,当一个次要级别出现时,选举是如何发生的

情况:我在两台计算机上设置了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。

    我实际得到的以及问题:当我关闭PC或终止它的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>
    


    对我来说有两点怀疑:

  • 考虑到这部分MongoDB文档:
  • 副本集使用选举来确定哪个集成员将成为主要成员。 在启动副本集之后进行选择,并且在任何时候主节点不可用。

    选举发生在小学不存在的时候(或者在发起时,但这部分不涉及我们的情况),但小学总是可用的,所以为什么选举发生。

  • 考虑到这部分相同的文档:
  • 如果副本集的大部分不可访问或不可用,则副本集不能接受写入,并且所有其余成员都变为只读。

    考虑到“成员变成只读”这个部分,我有两个节点和一个节点,所以这不会影响我们的复制。

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

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

    感谢万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>
    

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

    在这种情况下,如果仲裁器和辅助设备不可达,则主设备必须下台。 rs.status()应该能够确定副本成员的健康状况。

    你还应该注意的一件事是主oplog的大小。 oplog的大小决定了副本集成员可以关闭多长时间,并且在重新联机时仍能够赶上。 由于oplog可以容纳更多操作,因此oplog大小越大,可以处理会员的时间越长。 如果它落后得太远,则必须通过删除其数据文件并执行初始同步来重新同步该成员。

    请参阅检查Oplog的大小以获取更多信息。

    问候,

    丸。

    链接地址: http://www.djcxy.com/p/61651.html

    上一篇: In mongodb 3.0 replication, how elections happen when a secondary goes down

    下一篇: make replica set member passive without disconnecting clients?