[ MongoDB ] 副本集的搭建及测试
Replica Sets 复制 (副本集)
node1: 10.0.0.10
node2: 10.0.0.11
node3: 10.0.0.12
副本集结构图:
MongoDB程序,配置文件,启动脚本地址:链接:http://pan.baidu.com/s/1hslX7Ju 密码:jlei
node1 部署:
# 拷贝到其他两个节点上。 [root@node1 ~]# scp mongodb-linux-x86_64-rhel62-3.2.8.tgz 10.0.0.11:/root/ [root@node1 ~]# scp mongodb-linux-x86_64-rhel62-3.2.8.tgz 10.0.0.12:/root/ [root@node1 ~]# tar xf mongodb-linux-x86_64-rhel62-3.2.8.tgz -C /usr/local/ [root@node1 ~]# ln -vs /usr/local/mongodb-linux-x86_64-rhel62-3.2.8 /usr/local/mongodb `/usr/local/mongodb' -> `/usr/local/mongodb-linux-x86_64-rhel62-3.2.8 [root@node1 ~]# vim /etc/profile.d/mongod.sh [root@node1 ~]# source /etc/profile.d/mongod.sh # 建立运行mongodb服务的用户 [root@node1 ~]# useradd -s /sbin/nologin mongod # 创建mongodb配置文件及数据存放位置 [root@node1 ~]# mkdir -pv /mongodb/{conf,log,data} # 编写mongodb配置文件 [root@node1 ~]# vim /mongodb/conf/mongod.conf systemLog: destination: file ###日志存储位置 path: /mongodb/log/mongod.log logAppend: true storage: ##journal配置 journal: enabled: true ##数据文件存储位置 dbPath: /mongodb/data/ ##是否一个库一个文件夹 directoryPerDB: true ##数据引擎 engine: wiredTiger ##WT引擎配置 wiredTiger: engineConfig: ##WT最大使用cache(根据服务器实际情况调节) cacheSizeGB: 10 ##是否将索引也按数据库名单独存储 directoryForIndexes: true ##表压缩配置 collectionConfig: blockCompressor: zlib ##索引配置 indexConfig: prefixCompression: true processManagement: fork: true # fork and run in background pidFilePath: /var/run/mongodb/mongod.pid ##端口配置 net: port: 27017 bindIp: 10.0.0.10 # 配置副本集重要参数 replication: oplogSizeMB: 20 replSetName: rs0 # 创建日志文件 [root@node1 ~]# touch /mongodb/log/mongod.log [root@node1 ~]# chown -R mongod:mongod /mongodb/ # 编写服务启动脚本,该代码比较长,这里不再展示, [root@node1 ~]# vim /etc/init.d/mongod [root@node1 ~]# service mongod start Starting mongod: [ OK ] [root@node1 ~]# netstat -ntplu | grep mongod tcp 0 0 10.0.0.10:27017 0.0.0.0:* LISTEN 1592/mongod
node2、node3 配置和node1一样。
node2: [root@node2 data]# service mongod start Starting mongod: [ OK ] [root@node2 data]# netstat -ntplu | grep mongod tcp 0 0 10.0.0.11:27017 0.0.0.0:* LISTEN 1621/mongod node3: [root@bogon ~]# service mongod start Starting mongod: [ OK ] [root@bogon ~]# netstat -ntplu | grep mongod tcp 0 0 10.0.0.12:27017 0.0.0.0:* LISTEN 1996/mongod
node1 上进行配置
[root@node1 ~]# mongo 10.0.0.10:27017 > rs.status() { "info" : "run rs.initiate(...) if not yet done for the set", "ok" : 0, "errmsg" : "no replset config has been received", "code" : 94 } # 初始化副本集 > rs.initiate() { "info2" : "no configuration specified. Using a default configuration for the set", "me" : "10.0.0.10:27017", "ok" : 1 } # 添加node2和node3成员 rs0:PRIMARY> rs.add('10.0.0.11:27017') { "ok" : 1 } rs0:PRIMARY> rs.add('10.0.0.12:27017') { "ok" : 1 } rs0:PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2016-08-13T09:37:42.412Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "10.0.0.10:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 843, "optime" : { "ts" : Timestamp(1471081025, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-08-13T09:37:05Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1471080967, 2), "electionDate" : ISODate("2016-08-13T09:36:07Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "10.0.0.11:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 41, "optime" : { "ts" : Timestamp(1471081025, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-08-13T09:37:05Z"), "lastHeartbeat" : ISODate("2016-08-13T09:37:41.063Z"), "lastHeartbeatRecv" : ISODate("2016-08-13T09:37:42.065Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.0.0.10:27017", "configVersion" : 3 }, { "_id" : 2, "name" : "10.0.0.12:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 37, "optime" : { "ts" : Timestamp(1471081025, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-08-13T09:37:05Z"), "lastHeartbeat" : ISODate("2016-08-13T09:37:41.063Z"), "lastHeartbeatRecv" : ISODate("2016-08-13T09:37:42.065Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.0.0.10:27017", "configVersion" : 3 } ], "ok" : 1 } rs0:PRIMARY> rs.isMaster() { "hosts" : [ "10.0.0.10:27017", "10.0.0.11:27017", "10.0.0.12:27017" ], "setName" : "rs0", "setVersion" : 3, "ismaster" : true, "secondary" : false, "primary" : "10.0.0.10:27017", # primary节点是:10.0.0.10:27017 "me" : "10.0.0.10:27017", # 当前节点是:10.0.0.10:27017 "electionId" : ObjectId("7fffffff0000000000000001"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2016-08-13T09:38:07.799Z"), "maxWireVersion" : 4, "minWireVersion" : 0, "ok" : 1 }
测试:
通过primary节点添加1万条数据,看其他两个SECONDARY节点是否同步
rs0:PRIMARY> for(var i=1;i<=10000;i++) db.users.insert({id:i,addr_1:"Beijing",addr_2:"Shanghai"}); WriteResult({ "nInserted" : 1 }) rs0:PRIMARY> show dbs local 0.000GB test 0.000GB rs0:PRIMARY> use test switched to db test rs0:PRIMARY> show collections users rs0:PRIMARY> db.users.find() { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff5"), "id" : 1, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff6"), "id" : 2, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff7"), "id" : 3, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff8"), "id" : 4, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff9"), "id" : 5, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffa"), "id" : 6, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffb"), "id" : 7, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffc"), "id" : 8, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffd"), "id" : 9, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffe"), "id" : 10, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8fff"), "id" : 11, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9000"), "id" : 12, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9001"), "id" : 13, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9002"), "id" : 14, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9003"), "id" : 15, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9004"), "id" : 16, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9005"), "id" : 17, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9006"), "id" : 18, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9007"), "id" : 19, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9008"), "id" : 20, "addr_1" : "Beijing", "addr_2" : "Shanghai" }
# 查看 SECONDARY 节点
rs0:SECONDARY> show dbs 2015-12-07T03:32:41.419+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:761:19 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 # 首次在SECONDARY 访问集合的时候是不允许的。 rs0:SECONDARY> rs.slaveOk() # 首次访问集合需要执行rs.slaveOk() rs0:SECONDARY> show dbs local 0.000GB test 0.000GB rs0:SECONDARY> use test switched to db test rs0:SECONDARY> db.users.find() { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff5"), "id" : 1, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffd"), "id" : 9, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff6"), "id" : 2, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff7"), "id" : 3, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffe"), "id" : 10, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8fff"), "id" : 11, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffc"), "id" : 8, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff8"), "id" : 4, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ff9"), "id" : 5, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffa"), "id" : 6, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e8ffb"), "id" : 7, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9000"), "id" : 12, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9001"), "id" : 13, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9008"), "id" : 20, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9006"), "id" : 18, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9005"), "id" : 17, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9007"), "id" : 19, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9009"), "id" : 21, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9002"), "id" : 14, "addr_1" : "Beijing", "addr_2" : "Shanghai" } { "_id" : ObjectId("57aeecd04f49c2b3d60e9004"), "id" : 16, "addr_1" : "Beijing", "addr_2" : "Shanghai" } 以上结果就说明同步成功。
down掉PRIMARY服务,看看会出现什么状况
[root@node1 ~]# service mongod stop Stopping mongod: [ OK ] rs0:PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2015-12-06T19:36:07.801Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "10.0.0.10:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", # 检查到node1节点不健康。 "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2015-12-06T19:36:06.814Z"), "lastHeartbeatRecv" : ISODate("2015-12-06T19:35:37.559Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 1, "name" : "10.0.0.11:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", 将PRIMARY转交给node2成员 "uptime" : 1430, "optime" : { "ts" : Timestamp(1471081684, 2222), "t" : NumberLong(2) }, "optimeDate" : ISODate("2016-08-13T09:48:04Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1471081684, 2221), "electionDate" : ISODate("2016-08-13T09:48:04Z"), "configVersion" : 3, "self" : true }, { "_id" : 2, "name" : "10.0.0.12:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 965, "optime" : { "ts" : Timestamp(1471081684, 2222), "t" : NumberLong(2) }, "optimeDate" : ISODate("2016-08-13T09:48:04Z"), "lastHeartbeat" : ISODate("2015-12-06T19:36:06.813Z"), "lastHeartbeatRecv" : ISODate("2015-12-06T19:36:07.513Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.0.0.11:27017", "configVersion" : 3 } ], "ok" : 1 }
经过以上测试,实现了MongoDB副本集的高可用。