早期的mongodb类似mysql的master-slave模式,但是问题在于slave是只读的,一旦master挂掉,slave并不能切换成master。目前mongodb 早期的master-slave模式已经被淘汰,改成了副本集模式。
这个模式下有一个主(primary),一个或多个从(secondary),且支持每个节点设置权重,一旦primary当机,集群会根据权重选举新的primary出来。另外新架构还支持设置arbiter角色,它只负责裁决,并不真实存储数据。
说明:
(1)arbiter看实际需求是否真实启用。
(2)该架构读写都在primary上边,如果要做读写分离可以考虑多种方式,代码或代理服务器方式。
(3)设置好副本集以后, 第一个设置的集群默认为primary,然后可以从这个primary设置权重。以后集群会。
(4)副本集作用:增加冗余,提升数据安全;可以分担一部分读操作(次要)。
环境:centos 7.4
mongo:v4.2.1
node1:10.1.12.85
node1:10.1.12.90
node1:10.1.12.94
node1:10.1.12.95
node1:10.1.12.93
默认环境已经配置好。
ps:
(1)禁止iptalbes
(2)禁止selinux
(3)mongodb默认都监听了本机内网ip,并非只有127.0.0.1
(4)这里采用默认端口27017,实际生产中未必是这个端口,换枪不换药,原理一样的。
一,mongo集群搭建
机器基础环境安装好以后,针对mongo来讲,默认权重都为1. 后头我们单独设置权重。
ps:进行副本集搭建的时候,哪个机器开始进行设置,则默认这个机器开始为primary,其他都是secondary。
1,配置文件修改。
首先我们修改所有mongodb节点的配置文件/etc/mongod.conf,取消replication注释并添加内容:
replication: oplogSizeMB: 10240 replSetName: 21yunwei
这里oplogSizeMB类似mysql的binlog,大小根据实际大小来定;replSetName副本集名字根据实际项目命名,这里只是测试。修改以后完整的mongod.conf为:
systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log storage: dbPath: /var/lib/mongo journal: enabled: true processManagement: fork: true # fork and run in background pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile timeZoneInfo: /usr/share/zoneinfo net: port: 27017 bindIp: 127.0.0.1,10.1.12.93 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting. replication: oplogSizeMB: 10240 replSetName: 21yunwei
重启mongod服务,重启服务后即可生效。
2,搭建配置
进入node1,进行配置。
use admin config={_id:"21yunwei",members:[{_id:0,host:"10.1.12.85:27017"},{_id:1,host:"10.1.12.90:27017"},{_id:2,host:"10.1.12.94:27017"},{_id:3,host:"10.1.12.95:27017"},{_id:4,host:"10.1.12.93:27017"}]} rs.initiate(config) rs.status()
通过rs.status() 这里我们主要查看members下的”stateStr” : “SECONDARY”,状态,默认一开始5个节点都是secondary,需要等待选举生效。 (查资料默认是60S)
过后通过这个命令再去查看的时候,发现node1已经是primary,其他节点查看都已经变成secondary。
3,集群测试
思路:这里我们通过node1节点创建集合,插入数据;再进去其他secondary节点查看数据是否同步过去
进入primary,创建库,集合,插入数据等操作:
use dbtest db.user.insert({AccountID:1,UserName:"21yunwei",password:"123456"}) db.user.insert({AccountID:2,UserName:"22yunwei",password:"123456"})
从primary查看:
21yunwei:PRIMARY> show dbs admin 0.000GB config 0.000GB dbtest 0.000GB devops 0.000GB local 0.000GB test 0.000GB 21yunwei:PRIMARY> use dbtest switched to db dbtest 21yunwei:PRIMARY> show tables user 21yunwei:PRIMARY> db.user.find() { "_id" : ObjectId("5dd3a9a961425dca43627b0d"), "AccountID" : 1, "UserName" : "21yunwei", "password" : "123456" } { "_id" : ObjectId("5dd3b5bb7677656cf62f1fa1"), "AccountID" : 2, "UserName" : "22yunwei", "password" : "123456" } 21yunwei:PRIMARY> db.user.find({"AccountID":1}) { "_id" : ObjectId("5dd3a9a961425dca43627b0d"), "AccountID" : 1, "UserName" : "21yunwei", "password" : "123456" }
通过show dbs、show tables、查询都没啥问题。
下边我们进去node2 进入查看数据是否已经同步:
执行show dbs会报错如下:
21yunwei:SECONDARY> show tables 2019-11-19T17:27:54.319+0800 E QUERY [js] uncaught exception: Error: listCollections failed: { "operationTime" : Timestamp(1574155670, 1), "ok" : 0, "errmsg" : "not master and slaveOk=false",
原因node2 非master,需开启salve操作:
rs.slaveok()
再去执行:
21yunwei:SECONDARY> use dbtest switched to db dbtest 21yunwei:SECONDARY> show tables user 21yunwei:SECONDARY> db.user.find() { "_id" : ObjectId("5dd3a9a961425dca43627b0d"), "AccountID" : 1, "UserName" : "21yunwei", "password" : "123456" } { "_id" : ObjectId("5dd3b5bb7677656cf62f1fa1"), "AccountID" : 2, "UserName" : "22yunwei", "password" : "123456" }
发现数据已经过来了。 其他几个节点也要执行类似操作,这样副本集已经配置完成。
二,副本集故障测试与手工权重设置
1,故障测试
这里我们将node1 节点的mongo服务弄挂,停业务或加入iptables规则,然后进入node2查看集群状态。
node1测试iptables规则:
iptables -I INPUT -s 10.1.12.0 -p tcp -dport 27017 -j DROP
"members" : [ { "_id" : 0, "name" : "10.1.12.85:27017", "ip" : "10.1.12.85", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 540, "optime" : { "ts" : Timestamp(1574152904, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1574152904, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2019-11-19T08:41:44Z"), "optimeDurableDate" : ISODate("2019-11-19T08:41:44Z"), "lastHeartbeat" : ISODate("2019-11-19T08:41:45.891Z"), "lastHeartbeatRecv" : ISODate("2019-11-19T08:41:45.502Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "10.1.12.93:27017", "syncSourceHost" : "10.1.12.93:27017", "syncSourceId" : 4, "infoMessage" : "", "configVersion" : 1 }, { "_id" : 1, "name" : "10.1.12.90:27017", "ip" : "10.1.12.90", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 3397, "optime" : { "ts" : Timestamp(1574152904, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2019-11-19T08:41:44Z"), "syncingTo" : "10.1.12.93:27017", "syncSourceHost" : "10.1.12.93:27017", "syncSourceId" : 4, "infoMessage" : "", "configVersion" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "10.1.12.94:27017", "ip" : "10.1.12.94", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 2804, "optime" : {
这里发现node3 已经变成primary角色。
2,权重修改
首先,我们清空node1的规则:
iptables -F
进入node3节点(当前的primary节点)执行操作:
注意,手工进入设置的时候,必须进入primary节点进行设置才可以。
cfg = rs.conf() cfg.members[0].priority = 5 cfg.members[1].priority = 4 cfg.members[2].priority = 3 cfg.members[3].priority = 2 cfg.members[4].priority = 1 rs.reconfig(cfg) #应用配置触发选举
这样设置以后,等待生效以后,node1就会重新变成primary节点。权重高的节点会被重新选举为primary。这里一般用于手工调整primary节点。
21yunwei:PRIMARY> db.isMaster() { "hosts" : [ "10.1.12.85:27017", "10.1.12.90:27017", "10.1.12.94:27017", "10.1.12.95:27017", "10.1.12.93:27017" ], "setName" : "21yunwei", "setVersion" : 2, "ismaster" : true, "secondary" : false, "primary" : "10.1.12.85:27017", "me" : "10.1.12.85:27017", "electionId" : ObjectId("7fffffff0000000000000003"), "lastWrite" : { "opTime" : { "ts" : Timestamp(1574157970, 1), "t" : NumberLong(3) }, "lastWriteDate" : ISODate("2019-11-19T10:06:10Z"), "majorityOpTime" : { "ts" : Timestamp(1574157970, 1), "t" : NumberLong(3) }, "majorityWriteDate" : ISODate("2019-11-19T10:06:10Z") }, "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 100000,
转载请注明:21运维 » mongodb 副本集搭建与副本集测试