作者:链上研发-175405 时间:2017-01-04
副本集的意义在于冗余数据,提供数据库高可用性。副本集可以提供复制数据功能、特定场景下可以分担读写压力,提供延时备份的节点。。。
直接进入实战环节,创建三个mongod进程,包含两个数据节点和一个仲裁者节点,这三个节点需要网络互通:
mkdir -p /data/node1 mkdir -p /data/node2 mkdir -p /data/arbiter // 分别启动 mongod --replSet aha --dbpath /data/node1 --port 40001 mongod --replSet aha --dbpath /data/node2 --port 40002 mongod --replSet aha --dbpath /data/arbiter --port 40003 // 连接到node1 >rs.initiate({"_id":"aha","members":[ {"_id":0,"host":"server-1:40001"}, {"_id":1,"host":"server-2:40002"}, {"_id":2,"host":"server-3:40003","arbiterOnly":true} ]})一个最小副本集就已经搭建好了,可以使用命令查看个节点状态(因为我早就搭好了,所以主机名等一些参数都不相符):
Thu Jan 05 2017 01:04:27 GMT+0900 (JST)>rs.status() { "set" : "kancolle", "date" : ISODate("2017-01-04T16:04:34.978Z"), "myState" : 2, "term" : NumberLong(2), "syncingTo" : "sagedeMac-mini.local:40001", "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1483545871, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1483545871, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1483545871, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "sagedeMac-mini.local:40000", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 7057, "optime" : { "ts" : Timestamp(1483545871, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-01-04T16:04:31Z"), "syncingTo" : "sagedeMac-mini.local:40001", "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "sagedeMac-mini.local:40001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 7053, "optime" : { "ts" : Timestamp(1483545871, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1483545871, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-01-04T16:04:31Z"), "optimeDurableDate" : ISODate("2017-01-04T16:04:31Z"), "lastHeartbeat" : ISODate("2017-01-04T16:04:34.286Z"), "lastHeartbeatRecv" : ISODate("2017-01-04T16:04:34.688Z"), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1483538526, 1), "electionDate" : ISODate("2017-01-04T14:02:06Z"), "configVersion" : 3 }, { "_id" : 2, "name" : "sagedeMac-mini.local:40002", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 7053, "lastHeartbeat" : ISODate("2017-01-04T16:04:34.286Z"), "lastHeartbeatRecv" : ISODate("2017-01-04T16:04:31.800Z"), "pingMs" : NumberLong(0), "configVersion" : 3 } ], "ok" : 1 }可以看到两个数据节点中id为1的节点被选为主节点,id为0的节点为从节点。
先看看主节点可以干些什么:
Thu Jan 05 2017 01:17:44 GMT+0900 (JST)>db.test.insert({data:"test data 1"}) WriteResult({ "nInserted" : 1 }) Thu Jan 05 2017 01:18:03 GMT+0900 (JST)>db.test.find() { "_id" : ObjectId("586d203a79470d5f283d9205"), "data" : "test data 1" }好吧,主节点可以读写,和单节点的mongodb一样
再看看从节点:
Thu Jan 05 2017 01:20:41 GMT+0900 (JST)>show dbs 2017-01-05T01:20:51.307+0900 E QUERY [main] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" } : _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:755:19 shellHelper@src/mongo/shell/utils.js:645:15 @(shellhelp2):1:1 Thu Jan 05 2017 01:20:51 GMT+0900 (JST)>rs.slaveOk() Thu Jan 05 2017 01:21:15 GMT+0900 (JST)>show dbs admin 0.000GB kancolle 0.000GB local 0.000GB Thu Jan 05 2017 01:21:18 GMT+0900 (JST)>use kancolle switched to db kancolle Thu Jan 05 2017 01:21:29 GMT+0900 (JST)>db.test.find() { "_id" : ObjectId("586d203a79470d5f283d9205"), "data" : "test data 1" } Thu Jan 05 2017 01:21:35 GMT+0900 (JST)>db.test.insert({data:"test data 2"}) WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })好吧,从节点不但不允许写入,默认还不允许读取数据,需要连接驱动设置slaveOk才能读取数据。可以看到数据已经同步过来了。
最后是仲裁者,它不属于数据节点,不会成为主节点和从节点,仅仅参与选举主节点,也就是为了凑足“集合中大多数”的条件。
最后通过关闭主节点,来说明仲裁者的作用和副本集在主节点失效后是如何重新选举出新节点的(这里有张图是最好的)
connecting to: mongodb://localhost:40001 4 GMT+0900 (JST)>use admin switched to db admin // 关闭主节点 Thu Jan 05 2017 01:34:30 GMT+0900 (JST)>db.shutdownServer() server should be down... Thu Jan 05 2017 01:39:01 GMT+0900 (JST)>rs.isMaster() { "hosts" : [ "sagedeMac-mini.local:40000", "sagedeMac-mini.local:40001" ], "arbiters" : [ "sagedeMac-mini.local:40002" ], "setName" : "kancolle", "setVersion" : 3, "ismaster" : true, "secondary" : false, "primary" : "sagedeMac-mini.local:40000", "me" : "sagedeMac-mini.local:40000", "electionId" : ObjectId("7fffffff0000000000000003"), "lastWrite" : { "opTime" : { "ts" : Timestamp(1483547946, 1), "t" : NumberLong(3) }, "lastWriteDate" : ISODate("2017-01-04T16:39:06Z") }, "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2017-01-04T16:39:07.657Z"), "maxWireVersion" : 5, "minWireVersion" : 0, "readOnly" : false, "ok" : 1 }这里监督者节点和原来的从节点组成了3个节点中的“大部分”,在主节点下线的情况下,从节点变成了主节点,监督者节点永远还是监督者节点。,整个mongodb还能继续提供服务。
这次我们配置了副本集,通过主节点进行读写操作,验证了从节点的复制功能,最后让主节点下线使得整个副本集在从节点和监督者节点中重新选出新的主节点。
下篇会偏向理论一点,重新介绍副本集中的角色。
作者:链上研发-175405 时间:2017-01-04
