在centos7上搭建mongodb副本集
1.安装副本集介绍
副本集(Replica Set)是一组MongoDB实例组成的集群,由一个主(Primary)服务器和多个备份(Secondary)服务器构成。通过Replication,将数据的更新由Primary推送到其他实例上,在一定的延迟之后,每个MongoDB实例维护相同的数据集副本。通过维护冗余的数据库副本,能够实现数据的异地备份,读写分离和自动故障转移。
也就是说如果主服务器崩溃了,备份服务器会自动将其中一个成员升级为新的主服务器。使用复制功能时,如果有一台服务器宕机了,仍然可以从副本集的其他服务器上访问数据。如果服务器上的数据损坏或者不可访问,可以从副本集的某个成员中创建一份新的数据副本。
早期的MongoDB版本使用master-slave,一主一从和MySQL类似,但slave在此架构中为只读,当主库宕机后,从库不能自动切换为主。目前已经淘汰master-slave模式,改为副本集,这种模式下有一个主(primary),和多个从(secondary),只读。支持给它们设置权重,当主宕掉后,权重最高的从切换为主。在此架构中还可以建立一个仲裁(arbiter)的角色,它只负责裁决,而不存储数据。此架构中读写数据都是在主上,要想实现负载均衡的目的需要手动指定读库的目标server。
官方文档地址:https://docs.mongodb.com/manual/replication/
2.mongodb副本集搭建
由于在本地虚拟机中,机器有限,搭建伪集群模拟
首先安装启动三个mongod进程 端口分别是:27017,27108,27019
具体步骤如下:
2.1 依次启动mongodb服务
①解压
tar zxvf mongodb-linux-x86_64-rhel62-3.6.3.tgz
②修改名称
mv mongodb-linux-x86_64-rhel62-3.6.3 mongodb1
③创建相应的文件夹
cd mongodb1
mkdir data //数据目录
mkdir logs //日志目录
mkdir conf // 配置文件目录
cd conf
touch mongo.conf //新建配置文件
port=27017 dbpath=/home/lcc/mongodb1/data logpath=/home/lcc/mongodb1/logs/mongod.log fork = true //后台启动 bind_ip=0.0.0.0 replSet = replset //副本集的名称 |
④启动mongod服务
cd mongodb1
./bin/mongod -f conf/mongo.conf
至此mongodb1就启动起来了,依次启动mongodb2,mongodb3(注意修改暴露端口)
2.2 副本集配置
服务器启动之后,进入任意一个节点的命令行,将三个的实例关联起来
进入mongodb1的客户端:
cd mongodb1
./bin/mongo
> config = { ... _id : "replset", ... members : [ ... {_id : 0, host : "192.168.73.29:27017"}, ... {_id : 1, host : "192.168.73.29:27018"}, ... {_id : 2, host : "192.168.73.29:27019"}]} { "_id" : "replset", "members" : [ { "_id" : 0, "host" : "192.168.73.29:27017" }, { "_id" : 1, "host" : "192.168.73.29:27018" }, { "_id" : 2, "host" : "192.168.73.29:27019" } ] } |
初始化副本集的配置
rs.initiate(config) { "ok" : 1, "operationTime" : Timestamp(1520260635, 1), "$clusterTime" : { "clusterTime" : Timestamp(1520260635, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } replset:SECONDARY> |
当初始化配置信息后,可以明显的看到mongodb的命令行发生了变化,会显示出当前节点所属的副本集名称和节点类型。
再次进去mongodb1客户端:
发现mongodb1作为了主节点
至此,mongodb的副本集配置已经完成了,接下来是测试副本集是否可用
3.测试
3.1查看副本集状态
replset:SECONDARY> rs.config() { "_id" : "replset", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "192.168.73.129:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.73.129:27018", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.73.129:27019", "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("5b3c7d50a5952cfcd32c859b") } } replset:PRIMARY> |
3.2 查看主节点信息
replset:PRIMARY> rs.isMaster() { "hosts" : [ "192.168.73.129:27017", "192.168.73.129:27018", "192.168.73.129:27019" ], "setName" : "replset", "setVersion" : 1, "ismaster" : true, "secondary" : false, "primary" : "192.168.73.129:27017", "me" : "192.168.73.129:27017", "electionId" : ObjectId("7fffffff0000000000000001"), "lastWrite" : { "opTime" : { "ts" : Timestamp(1530690959, 1), "t" : NumberLong(1) }, "lastWriteDate" : ISODate("2018-07-04T07:55:59Z"), "majorityOpTime" : { "ts" : Timestamp(1530690959, 1), "t" : NumberLong(1) }, "majorityWriteDate" : ISODate("2018-07-04T07:55:59Z") }, "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 100000, "localTime" : ISODate("2018-07-04T07:56:08.530Z"), "logicalSessionTimeoutMinutes" : 30, "minWireVersion" : 0, "maxWireVersion" : 6, "readOnly" : false, "ok" : 1, "operationTime" : Timestamp(1530690959, 1), "$clusterTime" : { "clusterTime" : Timestamp(1530690959, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } replset:PRIMARY> |
3.3 数据测试
插入100条数据
replset:PRIMARY> show dbs admin 0.000GB config 0.000GB local 0.000GB test 0.000GB replset:PRIMARY> use test switched to db test replset:PRIMARY> for(var i = 0; i < 100; i++) { ... db.test.insert({order: i, name: "test" + i}) } WriteResult({ "nInserted" : 1 }) replset:PRIMARY> db.test.count() 100 replset:PRIMARY> |
进入副本节点查看数据是否同步
[lcc@localhost mongodb3]$ ./bin/mongo 192.168.73.129:27018 MongoDB shell version v3.6.3 connecting to: mongodb://192.168.73.129:27018/test MongoDB server version: 3.6.3 Server has startup warnings: 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2018-07-04T00:46:51.797-0700 I CONTROL [initandlisten] replset:SECONDARY> show dbs 2018-07-04T01:23:47.373-0700 E QUERY [thread1] Error: listDatabases failed:{ "operationTime" : Timestamp(1530692619, 1), "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk", "$clusterTime" : { "clusterTime" : Timestamp(1530692619, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:65:1 shellHelper.show@src/mongo/shell/utils.js:816:19 shellHelper@src/mongo/shell/utils.js:706:15 @(shellhelp2):1:1 replset:SECONDARY> |
当我们要查看从节点数据时,发现出错,这是因为从节点默认情况下是拒绝读取的,因此需开启读取功能
replset:SECONDARY> rs.slaveOk() |
接着再查看数据,发现已经同步了
replset:SECONDARY> use test switched to db test replset:SECONDARY> db.test.count() 100 |