MongoDB 复制集节点增加移除及节点属性配置

复制集(replica Set)或者副本集是MongoDB的核心高可用特性之一,它基于主节点的oplog日志持续传送到辅助节点,并重放得以实现主从节点一致。再结合心跳机制,当感知到主节点不可访问或宕机的情形下,辅助节点通过选举机制来从剩余的辅助节点中推选一个新的主节点从而实现自动切换。对于一个已经存在的MongoDB Replica Set集群,可以对其进行节点的增加,删除,以及修改节点属性等等。本文即是围绕这些进行描述。

有关MongoDB复制集概念及其搭建,可以参考:MongoDB 复制集(Replica Set)

一、节点的移除

//当前的演示环境
repSetTest:PRIMARY> db.version()
3.2.11

//主从节点
PRIMARY:   localhost:27001
SECONDARY: localhost:27000
SECONDARY: localhost:27002

repSetTest:PRIMARY> rs.remove("localhost:27000")
{ "ok" : 1 }

//移除节点后的状态信息
repSetTest:PRIMARY> rs.status()
{
        "set" : "repSetTest",
        "date" : ISODate("2016-08-30T05:48:13.010Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 1,
                        "name" : "localhost:27001",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 526,
                        "optime" : Timestamp(1472536085, 1),
                        "optimeDate" : ISODate("2016-08-30T05:48:05Z"),
                        "electionTime" : Timestamp(1472535890, 1),
                        "electionDate" : ISODate("2016-08-30T05:44:50Z"),
                        "configVersion" : 2,
                        "self" : true
                },
                {
                        "_id" : 2,
                        "name" : "localhost:27002",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 426,
                        "optime" : Timestamp(1472536085, 1),
                        "optimeDate" : ISODate("2016-08-30T05:48:05Z"),
                        "lastHeartbeat" : ISODate("2016-08-30T05:48:11.805Z"),
                        "lastHeartbeatRecv" : ISODate("2016-08-30T05:48:12.877Z"),
                        "pingMs" : 0,
                        "syncingTo" : "localhost:27001",
                        "configVersion" : 2
                }
        ],
        "ok" : 1
}

//移除后查看配置文件
//此时版本version为2,只有2个节点
repSetTest:PRIMARY> rs.config()
{
        "_id" : "repSetTest",
        "version" : 2,
        "members" : [
                {
                        "_id" : 1,
                        "host" : "localhost:27001",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

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

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

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

二、节点的增加

repSetTest:PRIMARY> rs.add("localhost:27000")
{ "ok" : 1 }
repSetTest:PRIMARY> rs.status()
{
        "set" : "repSetTest",
        "date" : ISODate("2016-08-30T05:50:56.678Z"),6
        "myState" : 1,
        "members" : [
                {
                        "_id" : 1,
                        "name" : "localhost:27001",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 689,
                        "optime" : Timestamp(1472536231, 1),
                        "optimeDate" : ISODate("2016-08-30T05:50:31Z"),
                        "electionTime" : Timestamp(1472535890, 1),
                        "electionDate" : ISODate("2016-08-30T05:44:50Z"),
                        "configVersion" : 3,
                        "self" : true
                },
                {
                        "_id" : 2,
                        "name" : "localhost:27002",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 590,
                        "optime" : Timestamp(1472536231, 1),
                        "optimeDate" : ISODate("2016-08-30T05:50:31Z"),
                        "lastHeartbeat" : ISODate("2016-08-30T05:50:55.336Z"),
                        "lastHeartbeatRecv" : ISODate("2016-08-30T05:50:55.063Z"),
                        "pingMs" : 0,
                        "configVersion" : 3
                },
                {
                        "_id" : 3,
                        "name" : "localhost:27000",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY", //增加后的节点此时作为一个从节点
                        "uptime" : 23,
                        "optime" : Timestamp(1472536231, 1),
                        "optimeDate" : ISODate("2016-08-30T05:50:31Z"),
                        "lastHeartbeat" : ISODate("2016-08-30T05:50:55.342Z"),
                        "lastHeartbeatRecv" : ISODate("2016-08-30T05:50:55.341Z"),
                        "pingMs" : 0,
                        "configVersion" : 3
                }
        ],
        "ok" : 1
}

三、启用Arbiter节点

repSetTest:PRIMARY> rs.remove("localhost:27000")
{ "ok" : 1 }

repSetTest:PRIMARY> rs.add({host:"localhost:27000",arbiterOnly:true})
{ "ok" : 1 }

repSetTest:PRIMARY> rs.config()
{
        "_id" : "repSetTest",
        "version" : 5,
        "members" : [
                {
                        "_id" : 1,
                        "host" : "localhost:27001",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,     // Author : Leshami
                        "priority" : 1,       // Blog   : http://blog.csdn.net/leshami
                        "tags" : {

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

                        },
                        "slaveDelay" : 0,
                        "votes" : 1
                },
                {
                        "_id" : 3,
                        "host" : "localhost:27000",
                        "arbiterOnly" : true,     //此处表明当前结点为仲裁节点
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

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

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

对于Arbiter也可以使用rs.addArb函数来添加
如:> rs.addArb("localhost:27000")

验证仲裁节点数据写入
repSetTest:PRIMARY> use tempdb
switched to db tempdb
repSetTest:PRIMARY> db.users.insert({id:1,ename:"robin"})
WriteResult({ "nInserted" : 1 })

# mongo localhost:27000
MongoDB shell version: 3.0.12
connecting to: localhost:27000/test
repSetTest:ARBITER> show dbs;
2016-08-30T14:26:26.753+0800 E QUERY    Error: listDatabases failed:
        { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }
    at Error (<anonymous>)
    at Mongo.getDBs (src/mongo/shell/mongo.js:47:15)
    at shellHelper.show (src/mongo/shell/utils.js:630:33)
    at shellHelper (src/mongo/shell/utils.js:524:36)
    at (shellhelp2):1:1 at src/mongo/shell/mongo.js:47

repSetTest:ARBITER> rs.slaveOk(true)
repSetTest:ARBITER> show dbs;    //执行该命令,看不到tempdb
local  0.281GB
test   0.031GB
repSetTest:ARBITER> use tempdb
switched to db tempdb
repSetTest:ARBITER> db.users.count() //执行count,提示节点正在恢复
2016-08-30T14:30:04.571+0800 E QUERY    Error: count failed:
        { "note" : "from execCommand", "ok" : 0, "errmsg" : "node is recovering" }
    at Error (<anonymous>)
    at DBQuery.count (src/mongo/shell/query.js:326:11)
    at DBCollection.count (src/mongo/shell/collection.js:1046:27)
    at (shell):1:10 at src/mongo/shell/query.js:326

四、设定节点的优先级别(Priority)

    优先级用于确定一个倾向成为主节点的程度。取值范围为0-100
    Priority 0节点的选举优先级为0,不会被选举为Primary,这样的成员称为被动成员
    对于跨机房复制集的情形,如A,B机房,最好将『大多数』节点部署在首选机房,以确保能选择合适的Primary
    对于Priority为0节点的情况,通常作为一个standby,或由于硬件配置较差,设置为0以使用不可能成为主

    //如下示例,在新增节点的时候设定该节点的优先级别
    repSetTest:PRIMARY> rs.add({"_id":3,"host":"localhost:27000","priority":1.5})

    也可以通过下面的方式修改优先级别
    repSetTest:PRIMARY> var config=rs.config()
    repSetTest:PRIMARY> config.members[2].priority=2
    2
    repSetTest:PRIMARY> rs.reconfig(config)
    { "ok" : 1 }

五、投票节点(Vote)

    投票节点不保存数据副本,不可能成为主节点
    Mongodb 3.0里,复制集成员最多50个,参与Primary选举投票的成员最多7个
    对于超出7个的其他成员(Vote0)的vote属性必须设置为0,即不参与投票

六、隐藏节点(Hidden)

    Hidden节点不能被选为主(Priority为0),并且对Driver不可见。
    因Hidden节点不会接受Driver的请求,可使用Hidden节点做一些数据备份、离线计算的任务,不会影响复制集的服务
    隐藏节点成员建议总是将其优先级设置为0(priority 0)
    由于对Driver不可见,因此不会作为read preference节点,隐藏节点可以作为投票节点
    在分片集群当中,mongos不会同隐藏节点交互

            > cfg = rs.conf()
            > cfg.members[2].priority = 0
            > cfg.members[2].hidden = true
            > rs.reconfig(cfg)

            查看设置为隐藏阶段后的属性
            repSetTest:SECONDARY> db.isMaster()
            {
                    "hosts" : [
                            "localhost:27000",
                            "localhost:27001"
                    ],
                    "setName" : "repSetTest",
                    "setVersion" : 2,
                    "ismaster" : false,
                    "secondary" : true,
                    "primary" : "localhost:27000",
                    "passive" : true,
                    "hidden" : true,     //此处表明当前节点为隐藏节点
                    "me" : "localhost:27002",
                    "maxBsonObjectSize" : 16777216,
                    "maxMessageSizeBytes" : 48000000,
                    "maxWriteBatchSize" : 1000,
                    "localTime" : ISODate("2017-03-06T10:15:48.257Z"),
                    "maxWireVersion" : 4,
                    "minWireVersion" : 0,
                    "ok" : 1
            }

七、延迟节点(Delayed)

    延迟节点包含复制集的部分数据,是复制集数据的子集
    延迟节点上的数据通常落后于Primary一段时间(可配置,比如1个小时)。
    当人为错误或者无效的数据写入Primary时,可通过Delayed节点的数据进行回滚
    延迟节点的要求:
            优先级别为0(priority 0),避免参与primary选举
            应当设置为隐藏节点(以避免应用程序查询延迟节点)
            可以作为一个投票节点,设置 members[n].votes 值为1
    延迟节点注意事项:
            延迟时间应当等于和大于维护窗口持续期
            应当小于oplog容纳数据的时间窗口 

            > cfg = rs.conf()
            > cfg.members[2].priority = 0
            > cfg.members[2].hidden = true
            > cfg.members[2].slaveDelay = 3600
            > rs.reconfig(cfg)

            repSetTest:SECONDARY> db.isMaster()
            {
                    "hosts" : [
                            "localhost:27000",
                            "localhost:27001"
                    ],
                    "setName" : "repSetTest",
                    "setVersion" : 3,
                    "ismaster" : false,
                    "secondary" : true,
                    "primary" : "localhost:27000",
                    "passive" : true,
                    "hidden" : true,
                    "slaveDelay" : 3600,    //此处表面当前节点具有延迟属性,为延迟节点
                    "me" : "localhost:27002",
                    "maxBsonObjectSize" : 16777216,
                    "maxMessageSizeBytes" : 48000000,
                    "maxWriteBatchSize" : 1000,
                    "localTime" : ISODate("2017-03-06T10:19:57.148Z"),
                    "maxWireVersion" : 4,
                    "minWireVersion" : 0,
                    "ok" : 1
            }

时间: 2024-12-03 09:31:41

MongoDB 复制集节点增加移除及节点属性配置的相关文章

仲裁节点-mongodb复制集数据恢复问题

问题描述 mongodb复制集数据恢复问题 我的primary库和仲裁节点在A服务器上,second库在B服务器上,现在的问题是A服务器挂了3天,然后恢复后重启主库和仲裁节点,但是在备库产生的3天数据却没同步回主库,请问各位大神是否有招,或者是有没有手动同步的方法

MongoDB复制集原理

复制集简介 Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写入Primary,Secondary从Primary同步写入的数据,以保持复制集内所有成员存储相同的数据集,提供数据的高可用. 下图(图片源于Mongodb官方文档)是一个典型的Mongdb复制集,包含一个Primary节点和2个Secondary节点. Primary选举 复制集通过replSetInitiate命令(或

MongoDB复制集自适应oplog管理

MongoDB复制集运行过程中,经常可能出现Secondary同步跟不上的情况,主要原因是主备写入速度上有差异,而复制集配置的oplog又太小,这时需要人工介入,向Secondary节点发送resync命令. 上述问题可通过配置更大的oplog来规避,目前官方文档建议的修改方案步骤比较长,而且需要停写服务来做,大致过程是先把oplog备份,然后再oplog集合删掉,重新创建,再把备份的内容导入到新创建的oplog. 我们团队)针对使用wiredtiger存储引擎的场景,开发了通过collMod命

MongoDB 复制集(Replica Set)

复制集(replica Set)或者副本集是MongoDB的核心高可用特性之一,它基于主节点的oplog日志持续传送到辅助节点,并重放得以实现主从节点一致.再结合心跳机制,当感知到主节点不可访问或宕机的情形下,辅助节点通过选举机制来从剩余的辅助节点中推选一个新的主节点从而实现自动切换.这个特性与MySQL MHA实现原理一样.本文主要描述MongoDB复制集并给出创建复制集示例以及完成自动切换. 一.复制集相关概念 复制集 复制是在多台服务器之间同步数据的过程,由一组Mongod实例(进程)组成

MongoDB复制集同步原理解析

MongoDB副本集数据同步](https://docs.mongodb.com/manual/core/replica-set-sync/)主要包含2个步骤 intial sync,可以理解为全量同步 replication,追同步源的oplog,可以理解为增量同步 本文是对MongoDB高可用复制集原理的补充,会详细介绍MongoDB数据同步的实现原理. initial sync Secondary节点当出现如下状况时,需要先进行全量同步 oplog为空 local.replset.minv

MongoDB Driver:使用正确的姿势连接复制集

MongoDB复制集(Replica Set)通过存储多份数据副本来保证数据的高可靠,通过自动的主备切换机制来保证服务的高可用.但需要注意的时,连接副本集的姿势如果不对,服务高可用将不复存在. 使用复制集时你需要知道的 MongoDB复制集里Primary节点是不固定的,当遇到复制集轮转升级.Primary宕机.网络分区等场景时,复制集可能会选举出一个新的Primary,而原来的Primary则会降级为Secondary,即发生主备切换. 总而言之,MongoDB复制集里Primary节点是不固

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

啊!你还不了解MongoDB复制集?先看这里科普一下 复制集的成员启动后,会选举出一个Primary,Primary需要得到大多数成员的投票.所有的写入操作都必须向Primary发起,通过oplog将写操作同步到Secondary. 在复制集运行的过程中,难免会遇到需要重启节点的场景,比如复制集版本升级.节点维护等,在重启节点的过程中,建议不要直接shutdown Primary,这样可能导致已经写入primary但未同步到secondary的数据丢失,过程类似如下: shutdown Prim

MongoDB原理:复制集状态同步机制

MongoDB复制集(3.0版本)之间通过心跳信息来同步成员的状态信息,每个节点会周期性的向复制集内其它的成员发送心跳信息来获取状态,如rs.status()看到的复制集状态信息. 一次心跳请求分3个阶段 (主动发起心跳请求的节点称为源,接受到心跳请求的成为目标) 源向目标发送心跳请求 目标处理心跳请求,并向源发送应答 源接受到心跳应答,更新目标节点状态 接下来将介绍这3个阶段里的主要状态同步逻辑 阶段1 默认配置下,复制集的节点每隔2s会向其他成员发送一次心跳请求,即发送replSetHear

MongoDB 3.4 复制集全量同步改进

3.2版本复制集同步的过程参考MongoDB 复制集同步原理解析 在 3.4 版本里 MongoDB 对复制集同步的全量同步阶段做了2个改进 在拷贝数据的时候同时建立所有的索引,在之前的版本里,拷贝数据时会先建立_id索引,其余的索引在数据拷贝完之后集中建立 在拷贝数据的同时,会把同步源上新产生的oplog拉取到本地local数据库的临时集合存储着,等数据全量拷贝完,直接读取本地临时集合的oplog来应用,提升了追增量的效率,同时也避免了同步源上oplog不足导致无法同步的问题. 上图描述了这2