MongoDB介绍
早期版本使用master-slave,一主一从和MySQL类似,但slave在此架构中为只读,当主库宕机后,从库不能自动切换为主
目前已经淘汰master-slave模式,改为副本集,这种模式下有一个主(primary),和多个从(secondary),只读。支持给它们设置权重,当主宕掉后,权重最高的从切换为主
在此架构中还可以建立一个仲裁(arbiter)的角色,它只负责裁决,而不存储数据
再此架构中读写数据都是在主上,要想实现负载均衡的目的需要手动指定读库的目标server
副本集架构图
MongoDB副本集搭建
三台机器: 192.168.109.130(primary) 192.168.109.132(secondary) 192.168.133.133(secondary)
编辑三台机器的配置文件,更改或增加:
replication:#把此行前面的#删除
##oplog大小
oplogSizeMB: 20#前面有两个空格
##复制集名称
replSetName: cclinux#前面有两个空格
分别重启三台机器
连接主,在主上运行命令mongo
>use admin
>config={_id:"cclinux",members:[{_id:0,host:"192.168.109.130:27017"},{_id:1,host:"192.168.109.132:27017"},{_id:2,host:"192.168.109.133:27017"}]}
>rs.initiate(config)
rs.status() #查看状态
如果两个从上的状态为"stateStr" : "STARTUP", 则需要进行如下操作
> var config={_id:"aminglinux",members:[{_id:0,host:"192.168.109.130:27017"},{_id:1,host:"192.168.109.132:27017"},{_id:2,host:"192.168.133.133:27017"}]}
>rs.reconfig(config)
此时再次查看rs.status()会发现从的状态变为SECONDARY
> use admin
switched to db admin
> config={_id:"cclinux",members:[{_id:0,host:"192.168.109.130:27017"},{_id:1,host:"192.168.109.132:27017"},{_id:2,host:"192.168.109.133:27017"}]}
{
"_id" : "cclinux",
"members" : [
{
"_id" : 0,
"host" : "192.168.109.130:27017"
},
{
"_id" : 1,
"host" : "192.168.109.132:27017"
},
{
"_id" : 2,
"host" : "192.168.109.133:27017"
}
]
}
> rs.initiate(config)
{ "ok" : 1 }
cclinux:OTHER> rs.status(config)
{
"set" : "cclinux",
"date" : ISODate("2018-11-20T12:20:46.256Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.109.130:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 445,
"optime" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-11-20T12:20:37Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1542716435, 1),
"electionDate" : ISODate("2018-11-20T12:20:35Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.109.132:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 22,
"optime" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-11-20T12:20:37Z"),
"optimeDurableDate" : ISODate("2018-11-20T12:20:37Z"),
"lastHeartbeat" : ISODate("2018-11-20T12:20:45.219Z"),
"lastHeartbeatRecv" : ISODate("2018-11-20T12:20:46.171Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.109.130:27017",
"syncSourceHost" : "192.168.109.130:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.109.133:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 22,
"optime" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1542716437, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-11-20T12:20:37Z"),
"optimeDurableDate" : ISODate("2018-11-20T12:20:37Z"),
"lastHeartbeat" : ISODate("2018-11-20T12:20:45.220Z"),
"lastHeartbeatRecv" : ISODate("2018-11-20T12:20:46.171Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.109.130:27017",
"syncSourceHost" : "192.168.109.130:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1
}
cclinux:PRIMARY> rs.status()
{
"set" : "cclinux",
"date" : ISODate("2018-11-20T12:22:30.269Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.109.130:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 549,
"optime" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-11-20T12:22:27Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1542716435, 1),
"electionDate" : ISODate("2018-11-20T12:20:35Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.109.132:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 126,
"optime" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-11-20T12:22:27Z"),
"optimeDurableDate" : ISODate("2018-11-20T12:22:27Z"),
"lastHeartbeat" : ISODate("2018-11-20T12:22:29.280Z"),
"lastHeartbeatRecv" : ISODate("2018-11-20T12:22:30.231Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.109.130:27017",
"syncSourceHost" : "192.168.109.130:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.109.133:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 126,
"optime" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1542716547, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-11-20T12:22:27Z"),
"optimeDurableDate" : ISODate("2018-11-20T12:22:27Z"),
"lastHeartbeat" : ISODate("2018-11-20T12:22:29.280Z"),
"lastHeartbeatRecv" : ISODate("2018-11-20T12:22:30.248Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.109.130:27017",
"syncSourceHost" : "192.168.109.130:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1
}
cclinux:PRIMARY> use mydb
switched to db mydb
cclinux:PRIMARY> db.acc.insert({AccountID:1,UserName:"123",password:"123456"})
WriteResult({ "nInserted" : 1 })
cclinux:PRIMARY> show dbs
admin 0.000GB
local 0.000GB
mydb 0.000GB
test 0.000GB
cclinux:PRIMARY> show tables
acc
MongoDB副本集测试
主上建库,建集合
>use mydb
>db.acc.insert({AccountID:1,UserName:"123",password:"123456"})
>show dbs
从上查看
>rs.slaveOk() #初始化
>show dbs
若出现错误Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" },需要执行
>rs.slaveok()
cc01主上执行 iptables -I INPUT -p tcp --dport 27017 -j DROP //自动切换,因为权重都是1所有主会随机切换的
cc01
root@cc01 php-fpm.d]# iptables -I INPUT -p tcp --dport 27017 -j DROP
[root@cc01 php-fpm.d]# mongo
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
2018-11-20T20:32:00.353+0800 W NETWORK [thread1] Failed to connect to 127.0.0.1:27017 after 5000ms milliseconds, giving up.
2018-11-20T20:32:00.353+0800 E QUERY [thread1] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed :
connect@src/mongo/shell/mongo.js:240:13
@(connect):1:6
exception: connect failed
cc02
[root@cc02 ~]# mongo
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
Server has startup warnings:
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten]
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten]
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten]
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten]
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-11-20T20:16:26.518+0800 I CONTROL [initandlisten]
cclinux:SECONDARY>
cc03
[root@cc03 ~]# mongo
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
Server has startup warnings:
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten]
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten]
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten]
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten]
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-11-20T20:16:17.225+0800 I CONTROL [initandlisten]
cclinux:PRIMARY>
cclinux:PRIMARY>
副本集更改权重模拟主宕机
默认三台机器权重都为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
在cc01上执行 iptables -D INPUT -p tcp --dport 27017 -j DROP 删除规则,再在cc03主上设置权重:
cclinux:PRIMARY> cfg = rs.conf()
{
"_id" : "cclinux",
"version" : 1,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "192.168.109.130:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "192.168.109.132:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "192.168.109.133: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("5bf3fc08bda65a68df9d4cee")
}
}
cclinux:PRIMARY> cfg.members[0].priority = 3
3
cclinux:PRIMARY> cfg.members[1].priority = 2
2
cclinux:PRIMARY> cfg.members[2].priority = 1
1
cclinux:PRIMARY> rs.reconfig(cfg)
{ "ok" : 1 }
cclinux:PRIMARY> rs.config()
2018-11-20T20:35:35.564+0800 E QUERY [thread1] Error: error doing query: failed: network error while attempting to run command 'replSetGetConfig' on host '127.0.0.1:27017' :
DB.prototype.runCommand@src/mongo/shell/db.js:132:1
DB.prototype.adminCommand@src/mongo/shell/db.js:150:16
rs.conf@src/mongo/shell/utils.js:1316:16
@(shell):1:1
2018-11-20T20:35:35.566+0800 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2018-11-20T20:35:35.566+0800 I NETWORK [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) ok
主由于之前主是cc03,现在规则一删除,权重设置后,主会自动跳到cc01上面去:
[root@cc01 php-fpm.d]# mongo
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
Server has startup warnings:
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten]
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten]
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten]
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten]
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-11-20T20:13:22.224+0800 I CONTROL [initandlisten]
cclinux:SECONDARY>
cclinux:PRIMARY> rs.config()
来源:oschina
链接:https://my.oschina.net/u/3867897/blog/2878990