MongoDB3:复制集

MongoDB复制集群的神奇之处在于本身就拥有自动容灾和选举的功能,不像mysql
需要借助中间件如mha和mysql-mmm来实现.mongodb复制集的从节点绝对不可写,
也不能指定只复制某个库或某个集合,集群只能有一个primary,服从大多数原则.

搭建与测试:
1>配置复制集:
conf = {_id:"yooo", members:[{_id:0,host:"127.0.0.1:28001"}, {_id:1,host:"127.0.0.1:28002"}} --配置复制集成员
rs.initiate(conf)  ---初始化复制集
rs.conf()             ---查看复制集成员配置,实际是在local数据库的system.replset集合里面文档,
                               可使用db.system.replset.find().pretty()查看和rs.conf()输出一样
rs.status()           ---查看复制集状态
rs.isMaster()
修改复制成员信息:不能修改_id,不能将接收rs.reconfig命令的成员的优先级设置为 0,不能将仲
                               裁者成员变为非仲裁者成员反正亦然,不能将 buildIndexes从false 改为 true
conf=rs.conf()
conf.members[1].hidden=true
rs.reconfig(conf)  或rs.reconfig(conf,{"force":true})强制重新配置

2>复制集节点属性:
_id和host: 集群节点的id,host为ip:port
priority:  整数,设置为0则永远不能成为主,数字越大越能成为主,如把复制集中某个节点的priority变成
               最大,而且该节点的optime与原主节点不超过10s,则原primary会降级,该节点升级成为新primary.
arbiterOnly: 是否是仲裁者
hidden:        是否隐藏节点
votes:           是否拥有投票权
slaveDlay:     复制延时时间
buildIndexes:当前节点是否把主上的index也clone过来,对_id限制无效

3>复制集节点类型:
主节点:提供读写服务的节点,-----priority至少为1
从节点:提供读服务的节点,包含下面:
              隐藏节点:对程序不可见的节点,------priority为0且hidden=true
                               rs.isMaster()不会显示隐藏节点,rs.status()依旧可以查看
              延时节点:延时复制的节点     ------priority为0且hidden=true,slaveDlay=XXX
              投票节点,具有投票权的节点  ------votes=1
arbiter:选举节点,无数据,仅做选举作用 ------arbiterOnly=true

1.配置文件,先启动2个实例
/etc/28001.conf,/etc/28002.conf,/etc/28003.conf
-----------------
port=28001
dbpath=/data/db1/28001
logpath=/data/db1/mongod.log
logappend=true
oplogSize=1024
fork=true
replSet=yooo
------------------
[root@rhel64-64bit etc]# ps -ef|grep mongo
root      1041     1  2 12:34 ?        00:00:02 ./mongod -f /etc/28001.conf
root      1108     1 16 12:35 ?        00:00:03 ./mongod -f /etc/28002.conf

2.在28001实例上配置并初始化复制集:
   ---配置复制集节点信息
> conf = {_id:"yooo", members:[{_id:0,host:"127.0.0.1:28001"}, {_id:1,host:"127.0.0.1:28002"}]}
{
	"_id" : "yooo",
	"members" : [
		{
			"_id" : 0,
			"host" : "127.0.0.1:28001"
		},
		{
			"_id" : 1,
			"host" : "127.0.0.1:28002"
		}
	]
}
> rs.initiate(conf)----初始化复制集群
{
	"ok" : 1,
	"operationTime" : Timestamp(1529988091, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1529988091, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
yooo:PRIMARY> rs.status() ---提示符已经变成的primary,查看集群状态
-----------------------------
yooo:PRIMARY> use local
yooo:PRIMARY> show tables
me
oplog.rs  ----记录oplog
replset.election
replset.minvalid
startup_log
system.replset  ----复制集的配置信息
system.rollback.id
------------------------------

yooo:PRIMARY> db
fooo
yooo:PRIMARY> db.foo.find()  ---主上创建数据库并插入数据
{ "_id" : ObjectId("5b31c49cdca108d5217c60c1"), "x" : 1, "y" : 1 }

3.在28002实例上查看:
yooo:SECONDARY> rs.slaveOk()   ---28002实例已加入集群是个从节点
yooo:SECONDARY> use fooo
switched to db fooo
yooo:SECONDARY> db.foo.find()  ---主上的数据已经同步过来
{ "_id" : ObjectId("5b31c49cdca108d5217c60c1"), "x" : 1, "y" : 1 }
yooo:SECONDARY> db.foo.insert({x:11,y:22})  ---从节点不可以写操作
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } }
4>添加新的集群节点:
内部过程:设置oplog的start日志点,新的节点会drop掉原有的数据库,并把复制源primary上的数据库
同步过来,然后从oplog的start点开始复制,可考虑用mongodump先同步数据
rs.add("new_node:port")---不需要rs.reconfig()
rs.addArb("new_node:port")
rs.add({'_id':5,"host":"new_node:port","arbiterOnly":true})
rs.remove("del_node:port")  --移除集群节点
4.先在28003实例上创建一些库和数据:
> show dbs
admin  0.000GB
aiya   0.000GB
local  0.000GB
> show tables
aiyaya
> db.aiyaya.find()
{ "_id" : ObjectId("5b31c840f5dacf8de3883762"), "x" : 123, "y" : 12345 }

5.在28001实例primary上添加28003实例进入yooo集群:
yooo:PRIMARY> rs.add("127.0.0.1:28003")
{
	"ok" : 1,
	"operationTime" : Timestamp(1529989365, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1529989365, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}

6.再次在28003实例上查看:
yooo:SECONDARY> rs.slaveOk()  --28003已经加入集群
yooo:SECONDARY> show dbs      --原有的数据库被drop掉并且clone了primary的库数据过来
admin   0.000GB
config  0.000GB
fooo    0.000GB
local   0.000GB
5>测试容灾:
1.停止28001实例: ./mongod -f /etc/28001.conf --shutdown
    查看复制集状态rs.status() ---28002实例已经成为新的primary了
	"members" : [
		{
			"_id" : 0,
			"name" : "127.0.0.1:28001",
			"health" : 0,
			"state" : 8,
			"stateStr" : "(not reachable/healthy)",  ---28001已经不可访问
		{
			"_id" : 1,
			"name" : "127.0.0.1:28002",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",    ----28002被选举成为新的primary
			"uptime" : 5151,

2.主动把primary降级为secondary
mongo>use admin
mongo>rs.stepDown(60)#单位为 秒
              rs.freeze(100) 100秒内不可以为主

6>查看复制集群状态:
rs.status()---查看复制集状态
mongo>db.serverStatus()
mongo>db.printReplicationInfo()  ---查看oplog状态
mongo>rs.printReplicationInfo()  
mongo>db.printSlaveReplicationInfo()
mongo>rs.printSlaveReplicationInfo() ---查看复制延时

yooo:PRIMARY> db.serverStatus().host
rhel64-64bit:28002
yooo:PRIMARY> rs.printSlaveReplicationInfo()
source: 127.0.0.1:28001
	syncedTo: Tue Jun 26 2018 14:54:09 GMT+0800 (HKT)
	0 secs (0 hrs) behind the primary 
source: 127.0.0.1:28003
	syncedTo: Tue Jun 26 2018 14:54:09 GMT+0800 (HKT)
	0 secs (0 hrs) behind the primary 

7>oplog作用类似于mysql里面的binlog:
oplog的结构:在默认情况下,oplog分配的是空闲磁盘空间的5%
ts:  时间戳,在选举新primary时,会选择ts最大的那个secondary作为primary
h:   此操作独一无二的ID
v:   oplog的版本
op:操作类型(i 代表insert,d代表 delete,u代表update,c代表db cmd,db代表声明当前数据库,n代表空操作)
ns: 操作所在的namespace-->一般显示是db.collection
o:   操作所对应的document,即当前操作的内容。
o2: 仅限于update操作时有,更新时的where条件

yooo:PRIMARY> db.oplog.rs.find().sort({$natural:-1}).limit(1).pretty()
{
	"ts" : Timestamp(1529992525, 1),
	"t" : NumberLong(3),
	"h" : NumberLong("-8501625235504890872"),
	"v" : 2,
	"op" : "n",
	"ns" : "",
	"wall" : ISODate("2018-06-26T05:55:25.884Z"),
	"o" : {
		"msg" : "periodic noop"
	}
}
调整oplog的大小:
1.如果是主节点,则先将primary 降为 secondary,rs.status()确保没有其他secondary 从该节点复制数据
   并以单机方式启动(即不加--replSet参数启动)
2.local.oplog.rs中的最新的一条保存的临时表:
   use local
   db.oplog.rs.find().sort({$natural:-1}).limit(1)
   db.temp.save(db.oplog.rs.find().sort({$natural:-1}).limit(1).next())
3.将oplog.rs 删除:
   db.oplog.rs.drop()
4.创建一个新的oplog.rs集合:
   db.createCollection("oplog.rs":{"capped":true,"size":10240})
5.将临时集合中的最后一条操作记录写回新创建的oplog.rs:
   db.oplog.rs.save(db.temp.findOne())
   db.oplog.rs.count()
6.加上replSet重启加入集群即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值