mongo回顾(十四:复制集)
首先简单的搭建mongodb复制集(一主两从),依旧采用docker
1,docker pull mongo
2,docker run --name s1 -p 27017:27017 -d mongo --replSet "RS"
修改port与name启动三个节点
--name 镜像启动的别名
-p 端口映射
-d 镜像名称
--replSet 集群名称
3,进入一个节点:docker exec -it s1 bash
4,执行initiate显示ok:1复制集就搭建好了
var config = {_id:"RS",members:[{_id:0,host:"127.0.0.1:27017"},{_id:1,host:"127.0.0.1:27018"},{_id:2,host:"127.0.0.1:27019"}]}
rs.initiate(config)
initiate.png
5,rs.status() 可以看到复制集状态(复制集可以只有单节点)
6,在从节点查看test库:db.test.find();可能报错,执行rs.slaveOk()即可
error.png
7,在主节点insert一条数据db.test.insert({a:1})
从节点db.test.find()可看到,则证明复制集搭建成功
使用复制集解决疑问
1,首先在主节点把一个从节点设置为延迟节点
https://docs.mongodb.com/manual/tutorial/configure-a-delayed-replica-set-member/
cfg = rs.conf()
cfg.members[2].priority = 0
cfg.members[2].hidden = true
cfg.members[2].secondaryDelaySecs = 36
rs.reconfig(cfg)
2,此时使用writeConcern 是等待状态:db.test.insert({count:3},{writeConcern:{w:3,j:true}})
且一个从节点很快,写入成功,一个需要等36S才成功
3,测试一:主节点执行db.test.insert({count:7},{writeConcern:{w:3,wtimeout:30000}})后,第一个节点写入成功,把第二个节点宕机,会发生什么
image.png
主节点显示超时,nInserted:1, find可以查到数据
image.png
宕机的节点,宕机前find是查不到数据的,重新启动数据可以查到
image.png
测试一说明writeConcern要求写入三个节点,写入途中一个节点宕机,其实仍然可以写入成功,当宕机的节点恢复后,数据仍会写入
4,测试二,主节点使用writeConcern写入3个节点,当从节点还没保存完成,主节点就宕机了。此时从节点数据会回滚吗?
主节点执行:db.test.insert({count:8},{writeConcern:{w:3,wtimeout:30000}})
主节点: 看到count:8
从节点一:看到count:8
从节点二:延时还没看到
docker kill s1
从节点一:变成主节点(从节点二执行 priority=0,没资格主节点),count:8数据还在
节点二:过一会儿看到count:8
恢复原来主节点:变成从节点,看到count:8
数据不会回滚,正常写入
5,测试三:只有三个节点,s1为主节点,s3为延时节点;主节点执行db.test.insert({count:12},{writeConcern:{w:4,wtimeout:10000}})后,数据是否正常插入
主节点:出现writeConcernError异常,数据正常插入
从节点s2: 数据正常插入
从节点s3: 到达延时时间后数据正常插入
image.png
6,测试四,只留主节点s1和延时节点s3,主节点执行db.test.insert({count:13},{writeConcern:{w:2,wtimeout:30000}})后,s3还没插入数据前使得s1宕机,s3到达延时时间可以正常插入数据吗
主节点:db.test.insert({count:13},{writeConcern:{w:2,wtimeout:30000}}),find可以看到数据
从节点s3:无法看到数据
docker kill s1
从节点s3(到达延时时间):可以看到数据
恢复从节点s2:从节点过一会变成主节点,find可以看到count:13数据
恢复s1:变成从节点,也能看到count:13
7,当副本集中只有1个节点活着,其他节点全部异常,此时仅存的节点会自动变成secondary,只能提供只读业务,无法提供写入业务。
8,测试只启动主节点s1,从节点s2;插入一条数据,s1,s2宕机,启动从节点s3,再启动s2,此时s3是否有数据
主节点:db.test.insert({count:14})
s1,s2宕机
s3启动(还是从节点),没count:14
s2启动被选举为主节点,有count:14
s3重新查询,发现count:14
writeConcern 虽然会增加写操作延迟时间,但并不会显著增加集群压力,因此无论是否等待,写操作最终都会复制到所有节点上。设置writeConcern只是让写操作等待复制后再返回而已
image.png那mongodb会发生回滚吗
会,回滚只会发生在主节点的写操作 没能 成功在 从节点 上应用就Down 掉的情况下
https://docs.mongodb.com/manual/core/replica-set-rollbacks/#std-label-rollback-data-files