MongoDB副本集:mysql
早期版本使用master-slave,一主一從和MySQL相似,但slave在此架構中爲只讀,當主庫宕機後,從庫不能自動切換爲主
目前已經淘汰master-slave模式,改成副本集,這種模式下有一個主(primary),和多個從(secondary),只讀。支持給它們設置權重,當主宕掉後,權重最高的從切換爲主
在此架構中還能夠創建一個仲裁(arbiter)的角色,它只負責裁決,而不存儲數據
再此架構中讀寫數據都是在主上,要想實現負載均衡的目的須要手動指定讀庫的目標serverlinux
副本集架構圖:
副本集primary宕機示意圖: sql
三臺機器: 192.168.133.130(primary) 192.168.133.132(secondary) 192.168.133.133(secondary)
編輯三臺機器的配置文件,更改或增長:
replication://把此行前面的#刪除
##oplog大小
oplogSizeMB: 20//前面有兩個空格
##複製集名稱
replSetName: aminglinux//前面有兩個空格
分別重啓三臺機器服務mongodb
鏈接主,在主上運行命令mongo >use admin >config={_id:"aminglinux",members:[{_id:0,host:"192.168.133.130:27017"},{_id:1,host:"192.168.133.132:27017"},{_id:2,host:"192.168.133.133:27017"}]} >rs.initiate(config) rs.status() //查看狀態 若是兩個從上的狀態爲"stateStr" : "STARTUP", 則須要進行以下操做 > var config={_id:"aminglinux",members:[{_id:0,host:"192.168.133.130:27017"},{_id:1,host:"192.168.133.132:27017"},{_id:2,host:"192.168.133.133:27017"}]} >rs.reconfig(config) 此時再次查看rs.status()會發現從的狀態變爲SECONDARY
> use admin switched to db admin > config={_id:"aminglinux",members:[{_id:0,host:"192.168.60.11:27017"},{_id:1,host:"192.168.60.12:27017"},{_id:2,host:"192.168.60.13:27017"}]} { "_id" : "aminglinux", "members" : [ { "_id" : 0, "host" : "192.168.60.11:27017" }, { "_id" : 1, "host" : "192.168.60.12:27017" }, { "_id" : 2, "host" : "192.168.60.13:27017" } ] } > > rs.initiate(config) { "ok" : 1 } ##是1 就對了; aminglinux:PRIMARY> rs.status() ##查看狀態; { "set" : "aminglinux", "date" : ISODate("2017-10-19T19:41:16.726Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "192.168.60.11:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 2851, "optime" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-10-19T19:41:14Z"), "electionTime" : Timestamp(1508439306, 1), "electionDate" : ISODate("2017-10-19T18:55:06Z"), "configVersion" : 6, "self" : true }, { "_id" : 2, "name" : "192.168.60.12:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 75, "optime" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-10-19T19:41:14Z"), "optimeDurableDate" : ISODate("2017-10-19T19:41:14Z"), "lastHeartbeat" : ISODate("2017-10-19T19:41:16.633Z"), "lastHeartbeatRecv" : ISODate("2017-10-19T19:41:14.635Z"), "pingMs" : NumberLong(0), "syncingTo" : "192.168.60.11:27017", "configVersion" : 6 }, { "_id" : 3, "name" : "192.168.60.13:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 0, "optime" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1508442074, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-10-19T19:41:14Z"), "optimeDurableDate" : ISODate("2017-10-19T19:41:14Z"), "lastHeartbeat" : ISODate("2017-10-19T19:41:16.630Z"), "lastHeartbeatRecv" : ISODate("2017-10-19T19:41:16.645Z"), "pingMs" : NumberLong(0), "syncingTo" : "192.168.60.11:27017", "configVersion" : 6 } ], "ok" : 1 }
MongoDB副本集測試:shell
主上建庫,建集合 >use mydb >db.acc.insert({AccountID:1,UserName:"123",password:"123456"}) >show dbs 從上查看 >show dbs 若出現錯誤Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" },須要執行 >rs.slaveok()
aminglinux:PRIMARY> use mysql ##在從上面建立mysql switched to db mysql aminglinux:PRIMARY> db.acc.insert({AccountID:1,UserName:"123",password:"123456"}) ##建立一個集合acc,並插入數據 WriteResult({ "nInserted" : 1 }) aminglinux:PRIMARY> show dbs; db1 0.000GB local 0.000GB mysql 0.000GB ##接下來咱們等了60.12secondary查看同步 aminglinux:SECONDARY> show dbs 2017-10-19T20:47:39.795+0800 E QUERY [thread1] 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:769:19 shellHelper@src/mongo/shell/utils.js:659:15 @(shellhelp2):1:1 aminglinux:SECONDARY> rs.slaveOk() ##執行這個,讓slave能夠查看; aminglinux:SECONDARY> show dbs db1 0.000GB local 0.000GB mysql 0.000GB
副本集更改權重模擬主宕機:服務器
默認三臺機器權重都爲1,若是任何一個權重設置爲比其餘的高,則該臺機器立刻切換爲primary角色,因此咱們預設三臺機器的權重分別爲:130:3,132:2,133:1 在主上執行 cfg = rs.conf() cfg.members[0].priority = 3 cfg.members[1].priority = 2 cfg.members[2].priority = 1 rs.reconfig(cfg) 這樣的話,第二個節點將會成爲候選主節點。 主上執行 iptables -I INPUT -p tcp --dport 27017 -j DROP
aminglinux:PRIMARY> rs.config() ##查看配置,priority是其權重 { "_id" : "aminglinux", "version" : 6, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "192.168.60.11:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.60.12:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "192.168.60.13: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" : 60000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("59e8f4ffee48611ad04ee633") } } [root@Dasoncheng ~]# iptables -I INPUT -p tcp --dport 27017 -j DROP ##在primary上面執行這條命令,drop掉27017端口的通訊;在其餘副本集查看狀態 aminglinux:PRIMARY> rs.status() ##60.12已經成爲primary了; { "set" : "aminglinux", "date" : ISODate("2017-10-19T13:04:55.021Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1508443618, 5), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1508443618, 5), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1508443618, 5), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "192.168.60.11:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2017-10-19T13:04:50.892Z"), "lastHeartbeatRecv" : ISODate("2017-10-19T13:04:54.910Z"), "pingMs" : NumberLong(1), "lastHeartbeatMessage" : "Couldn't get a connection within the time limit", "configVersion" : -1 }, { "_id" : 2, "name" : "192.168.60.12:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 6295, "optime" : { "ts" : Timestamp(1508443618, 5), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-10-19T20:06:58Z"), "electionTime" : Timestamp(1508443618, 2), "electionDate" : ISODate("2017-10-19T20:06:58Z"), "configVersion" : 6, "self" : true }, { "_id" : 3, "name" : "192.168.60.13:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 1591, "optime" : { "ts" : Timestamp(1508443618, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1508443618, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-10-19T20:06:58Z"), "optimeDurableDate" : ISODate("2017-10-19T20:06:58Z"), "lastHeartbeat" : ISODate("2017-10-19T13:04:53.973Z"), "lastHeartbeatRecv" : ISODate("2017-10-19T13:04:53.173Z"), "pingMs" : NumberLong(1), "syncingTo" : "192.168.60.11:27017", "configVersion" : 6 } ], "ok" : 1 } ##在這裏呢,由於權重都爲1 全部選擇primary具備隨機性;咱們這裏設置權重來指定 aminglinux:PRIMARY> cfg=rs.conf() ##設置一個變量,下面爲設置權重 aminglinux:PRIMARY> cfg.members[0].priority = 3 3 aminglinux:PRIMARY> cfg.members[1].priority = 2 2 aminglinux:PRIMARY> cfg.members[2].priority = 1 1 aminglinux:PRIMARY> rs.reconfig(cfg) ##從新加載配置 { "ok" : 1 } 2017-10-19T21:10:12.635+0800 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed 2017-10-19T21:10:12.638+0800 I NETWORK [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) ok aminglinux:SECONDARY> rs.config() ##咱們能夠看到,60.12已經變成secondary了; { "_id" : "aminglinux", "version" : 7, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "192.168.60.11:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 3, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.60.12:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 2, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "192.168.60.13: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" : 60000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("59e8f4ffee48611ad04ee633") } }
小提示:這是副本集的操做; rs.slaveOk();--sencondary機器受權查詢
rs.isMaster()--查看副本集狀態
rs.status()--查看副本集狀態
rs.remove("localhost:20001");--刪除節點 在主服務器執行
rs.add("localhost:20001");--增長節點
rs.initiate(config_rs1);--Initializes a new replica set.
rs.reconfig(config_rs1);--Re-configures a replica set by applying a new replica set configuration object.
rs.的命令官網
http://docs.mongodb.org/manual/reference/method/js-replication/
Replica Set官網說明:
http://docs.mongodb.org/manual/core/replica-set-architecture-three-members/架構