MongoDB的集群模式 Replica Set

一、Replica Set 集群分为两种架构: 奇数个节点构成Replica Set,所有节点拥有数据集。 最小架构: 1个Primary节点,2个Secondary节点 偶数个节点 + 一个仲裁节点 构成的Replica Set,节点拥有数据

    <p>一、Replica Set 集群分为两种架构:</p>

奇数个节点构成Replica Set,所有节点拥有数据集。最小架构: 1个Primary节点,2个Secondary节点

偶数个节点 + 一个仲裁节点 构成的Replica Set,节点拥有数据集,仲裁节点仅参与仲裁选举出Primary节点。 最小架构:1个Primary节点,1个Secondary节点,1个Arbiter节点  

接下来就以3台服务器为例,部署具有仲裁的框架。

IP地址 操作系统版本 MongoDB版本 端口 功能 10.10.18.10 CentOS7.5  4.0  27017  Primary  10.10.18.11 Centos7.5  4.0  27017  Secondary 10.10.18.12 Centos7.5  4.0  27017  Arbiter

二、安装部署(请访问 "MongoDB安装")https://www.558idc.com/Linux/2019-07/159249.htm

Primary的配置文件:

systemLog: destination: file path: "/data/mongodb/log/mongod.log" logAppend: true storage: dbPath: "/data/mongodb/data" journal: enabled: true wiredTiger: engineConfig: cacheSizeGB: 2 processManagement: fork: true pidFilePath: "/data/mongodb/pid/m.pid" net: bindIp: 10.10.18.10 port: 27017 replication: replSetName: "rs0"

Secondary的配置文件

systemLog: destination: file path: "/data/mongodb/log/mongod.log" logAppend: true storage: dbPath: "/data/mongodb/data" journal: enabled: true wiredTiger: engineConfig: cacheSizeGB: 2 processManagement: fork: true pidFilePath: "/data/mongodb/pid/m.pid" net: bindIp: 10.10.18.11 port: 27017replication: replSetName: "rs0"

Arbiter的配置文件

systemLog: destination: file path: "/data/mongodb/log/mongod.log" logAppend: true storage: dbPath: "/data/mongodb/data" journal: enabled: true wiredTiger: engineConfig: cacheSizeGB: 2 processManagement: fork: true pidFilePath: "/data/mongodb/pid/m.pid" net: bindIp: 10.10.18.12 port: 27017replication: replSetName: "rs0"

启动三台服务器上的mongdb

mongod -f /data/mongodb/mongod.conf

关闭进程

mongod -f /data/mongodb/mongod.conf --shutdown

三、配置Replica Set

登录三台服务器中任意一台,登录mongo(如果报错就将配置文件中:security 内容暂时先去掉)

mongo --host 10.10.18.10

>cfg={ _id:"rs0",members:[{_id:0,host:'10.10.18.10:27017',priority:1},{_id:1,host:'10.10.18.11:27017',priority:1},{_id:2,host:'10.10.18.12:27017',arbiterOnly:true}] };

>rs.initiate(cfg)

查看Replica Set配置

> rs.conf()

{"_id" : "rs0","version" : 1,"protocolVersion" : NumberLong(1),"writeConcernMajorityJournalDefault" : true,"members" : [{"_id" : 0,"host" : "10.10.18.10:27017","arbiterOnly" : false,"buildIndexes" : true,"hidden" : false,"priority" : 1,"tags" : {

},"slaveDelay" : NumberLong(0),"votes" : 1},{"_id" : 1,"host" : "10.10.18.11:27017","arbiterOnly" : false,"buildIndexes" : true,"hidden" : false,"priority" : 1,"tags" : {

},"slaveDelay" : NumberLong(0),"votes" : 1},{"_id" : 2,"host" : "10.10.18.12:27017","arbiterOnly" : true,"buildIndexes" : true,"hidden" : false,"priority" : 0,"tags" : {

},"slaveDelay" : NumberLong(0),"votes" : 1}],"settings" : {"chainingAllowed" : true,"heartbeatIntervalMillis" : 2000,"heartbeatTimeoutSecs" : 10,"electionTimeoutMillis" : 10000,"catchUpTimeoutMillis" : -1,"catchUpTakeoverDelayMillis" : 30000,"getLastErrorModes" : {

},"getLastErrorDefaults" : {"w" : 1,"wtimeout" : 0},"replicaSetId" : ObjectId("5cff76e5e57e23a5bc7054e2")}}

四、验证Replica Set

在Primary中插入数据

rs0:PRIMARY> show dbs admin 0.000GB config 0.000GB local 0.000GB rs0:PRIMARY> db.users.insertOne( ... { ... name:"sue", ... age: 26, ... status:"pending" ... }) { "acknowledged" : true, "insertedId" : ObjectId("5cff79e8993e70290a081d04") }

rs0:PRIMARY> db.users.find(){ "_id" : ObjectId("5cff79e8993e70290a081d04"), "name" : "sue", "age" : 26, "status" : "pending" }

在Secondary中,默认是不允许读

rs0:SECONDARY> db.users.find() Error: error: { "operationTime" : Timestamp(1560247181, 1), "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk", "$clusterTime" : { "clusterTime" : Timestamp(1560247181, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }

五、创建用户 https://www.558idc.com/Linux/2019-07/159238.htm

六、故障模拟

停止Primary上的mongo进程,在Secondary上登录mongo查看

mongo --host 10.10.18.11 rs0:PRIMARY> db.users.find() { "_id" : ObjectId("5cff79e8993e70290a081d04"), "name" : "sue", "age" : 26, "status" : "pending" }

发现原Secondary变成Primary,并且可以进行查询。

开启原Primary服务器上的mongo进程,该服务器变成了Secondary。

七、数据备份和恢复

mongodump从MongoDB中读取数据,保存为BSON文件,mongorestore读取BSON文件恢复到MongoDB中。适用于小型MongoDB的备份和恢复。

mongodump备份的时候只备份MongoDB中的文档,使用mongorestore恢复之后需要重建索引

mongodump --host 10.10.18.11 --port 27017 --username myUserAdmin --password abc123 --gzip --out /data/mongobak/$(date +%F)注:--oplog 表示备份的时候oplog.bson文件,存放在dump开始 到 dump结束之间所有的oplog。

根据前面的备份恢复到一个新的Replica Set集群中其中一台服务器上。

恢复

恢复的过程中,不要启用认证。否则在将其他机器加入到Replica Set集群中来的时候,会出现无法认证的问题。

1、首先在一台服务器上开启一个干净mongo服务(无任何数据),做为 Primary

mongd.conf配置文件内容

systemLog: destination: file path: "/data/mongodb/log/mongod.log" logAppend: true storage: dbPath: "/data/mongodb/data" journal: enabled: true wiredTiger: engineConfig: cacheSizeGB: 2 processManagement: fork: true pidFilePath: "/data/mongodb/pid/mongod.pid" net: bindIp: 10.10.18.10 port: 27017 replication: replSetName: "rs0"

2、开启mongod服务

/data/mongodb/bin/mongod -f /data/mongodb/mongod.conf

3、创建单个Replica Set

登录mongo,然后创建单个Replica Set

mongo --host 10.10.18.10 > cfg={_id:"rs0",members:[{_id:0,host:'10.10.18.10:27017',priority:1}]} > rs.initiate(cfg)

创建结果:

{        "ok" : 1,        "operationTime" : Timestamp(1560394449, 1),        "$clusterTime" : {                "clusterTime" : Timestamp(1560394449, 1),                "signature" : {                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),                        "keyId" : NumberLong(0)                }        }}

创建好了之后,就可以查看当前的数据库

rs0:SECONDARY> show dbs admin 0.000GB config 0.000GB local 0.000GB

可以发现,目前就三个基本的数据库。

4、恢复数据

mongorestore --host 10.10.18.10 --port 27017 --gzip /data/mongobak/2019-06-12

结果

2019-06-13T10:55:33.817+0800    preparing collections to restore from2019-06-13T10:55:33.829+0800    reading metadata for admin.test from /data/mongobak/2019-06-12/admin/test.metadata.json.gz2019-06-13T10:55:33.832+0800    reading metadata for test.users from /data/mongobak/2019-06-12/test/users.metadata.json.gz2019-06-13T10:55:33.834+0800    reading metadata for reporting.reporting from /data/mongobak/2019-06-12/reporting/reporting.metadata.json.gz2019-06-13T10:55:33.841+0800    reading metadata for admin.reporting from /data/mongobak/2019-06-12/admin/reporting.metadata.json.gz2019-06-13T10:55:33.861+0800    restoring test.users from /data/mongobak/2019-06-12/test/users.bson.gz2019-06-13T10:55:34.085+0800    restoring admin.test from /data/mongobak/2019-06-12/admin/test.bson.gz2019-06-13T10:55:34.123+0800    no indexes to restore2019-06-13T10:55:34.123+0800    finished restoring test.users (1 document)2019-06-13T10:55:34.123+0800    restoring admin.reporting from /data/mongobak/2019-06-12/admin/reporting.bson.gz2019-06-13T10:55:34.175+0800    restoring reporting.reporting from /data/mongobak/2019-06-12/reporting/reporting.bson.gz2019-06-13T10:55:34.230+0800    no indexes to restore2019-06-13T10:55:34.230+0800    finished restoring admin.test (2 documents)2019-06-13T10:55:34.233+0800    no indexes to restore2019-06-13T10:55:34.233+0800    finished restoring reporting.reporting (1 document)2019-06-13T10:55:34.234+0800    no indexes to restore2019-06-13T10:55:34.234+0800    finished restoring admin.reporting (1 document)2019-06-13T10:55:34.234+0800    restoring users from /data/mongobak/2019-06-12/admin/system.users.bson.gz2019-06-13T10:55:34.312+0800    done

恢复完成,在登录mongo查看,恢复数据库的情况。

rs0:PRIMARY> show dbsadmin      0.000GBconfig    0.000GBlocal      0.000GBreporting  0.000GBtest      0.000GBrs0:PRIMARY> use testswitched to db testrs0:PRIMARY> show collectionsusersrs0:PRIMARY> db.users.find(){ "_id" : ObjectId("5cff79e8993e70290a081d04"), "name" : "sue", "age" : 26, "status" : "pending" }

可以看出之前的记录已经恢复了。

注意:如果备份时,MongoDB是拥有用户名和密码才能进行登录的,在恢复之后,用户名和密码也是可以使用的。如果需要在使用认证登录,需要将下面信息添加的配置文件mongod.conf:

security: keyFile: "/data/mongodb/keyfile" authorization: "enabled"

然后重启mongo服务。

5、关闭刚恢复的MongoDB,将数据目录同步到另一台服务器上,作为Secondary

通过之前,确认该台服务器上的mongo是无任何数据。将Primary服务上的 /data/mongodb/data 同步到 Secondary服务器上  /data/mongodb/data

6、依次开启Primary、Secondary、Arbiter的mongo服务

7、在Primary服务器上,将Secondary、Arbiter加入到Replica Set集群中来

查看当前Replica Set集群的配置

rs0:PRIMARY> rs.conf() { "_id" : "rs0", "version" : 1, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "10.10.18.10:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {

                    },
                    "slaveDelay" : NumberLong(0),
                    "votes" : 1
            }
    ],
    "settings" : {
            "chainingAllowed" : true,
            "heartbeatIntervalMillis" : 2000,
            "heartbeatTimeoutSecs" : 10,
            "electionTimeoutMillis" : 10000,
            "catchUpTimeoutMillis" : -1,
            "catchUpTakeoverDelayMillis" : 30000,
            "getLastErrorModes" : {

            },
            "getLastErrorDefaults" : {
                    "w" : 1,
                    "wtimeout" : 0
            },
            "replicaSetId" : ObjectId("5d01bad15dfd3f294d147b36")
    }

}

可以看到当前Replica Set集群中就一台服务器

将Secondary、Arbiter加入到Replica Set集群中

rs0:PRIMARY> rs.add( ... { ... _id: 1, ... host:'10.10.18.11:27017', ... priority:1 ... } ... ) { "ok" : 1, "operationTime" : Timestamp(1560397822, 1), "$clusterTime" : { "clusterTime" : Timestamp(1560397822, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } rs0:PRIMARY> rs.add( ... { ... _id: 2, ... host:'10.10.18.12:27017', ... arbiterOnly:true ... } ... ) { "ok" : 1, "operationTime" : Timestamp(1560397830, 1), "$clusterTime" : { "clusterTime" : Timestamp(1560397830, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) }

再次查看状态:

rs0:PRIMARY> rs.conf() { "_id" : "rs0", "version" : 3, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "10.10.18.10:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {

                    },
                    "slaveDelay" : NumberLong(0),
                    "votes" : 1
            },
            {
                    "_id" : 1,
                    "host" : "10.10.18.11:27017",
                    "arbiterOnly" : false,
                    "buildIndexes" : true,
                    "hidden" : false,
                    "priority" : 1,
                    "tags" : {

                    },
                    "slaveDelay" : NumberLong(0),
                    "votes" : 1
            },
            {
                    "_id" : 2,
                    "host" : "10.10.18.12:27017",
                    "arbiterOnly" : true,
                    "buildIndexes" : true,
                    "hidden" : false,
                    "priority" : 0,
                    "tags" : {

                    },
                    "slaveDelay" : NumberLong(0),
                    "votes" : 1
            }
    ],
    "settings" : {
            "chainingAllowed" : true,
            "heartbeatIntervalMillis" : 2000,
            "heartbeatTimeoutSecs" : 10,
            "electionTimeoutMillis" : 10000,
            "catchUpTimeoutMillis" : -1,
            "catchUpTakeoverDelayMillis" : 30000,
            "getLastErrorModes" : {

            },
            "getLastErrorDefaults" : {
                    "w" : 1,
                    "wtimeout" : 0
            },
            "replicaSetId" : ObjectId("5d01bad15dfd3f294d147b36")
    }

}

加入成功。

开启认证访问

在三台服务器的配置文件中添加:

security: keyFile: "/data/mongodb/keyfile" authorization: "enabled"

然后依次关闭:Arbiter Secondary Primary

依次开启:Primary Secondary Arbiter

security: keyFile: "/data/mongodb/keyfile" authorization: "enabled"