MongoDB ReplicaSet

在mongodb中,数据同步有两种类型:
master/slave:主从。已经废弃,被副本集取代。
replica set:副本集。

一个副本集只能有一个主节点,可以有多个从节点。主节点可以读写,从节点只能读。

https://docs.mongodb.com/v2.6/core/replica-set-members/

主节点将数据修改操作保存至oplog中。

需要奇数个节点,至少三个节点。
心跳信息每两秒传递一次。
通过选举,实现自动故障转移。主节点宕机后会进行自动选举。

副本集中的从节点的特殊类型:

https://docs.mongodb.com/v2.6/core/replica-set-secondary/
1、0优先级节点:冷备节点,参与选举,但不会被选举成为主节点。
2、隐藏的从节点:首先是一个0优先级节点,并且对客户端不可见。
3、延迟复制从节点:首先是一个0优先级节点,并且复制时间落后于主节点一个固定时长。持有的数据始终为过期数据。
4、arbiter:仲裁节点,不持有数据。

oplog:每个节点都有oplog,但只有主节点会写oplog,然后同步给从节点。是一个大小固定的文件,存储在local库中。

新加入的节点数据同步的过程:
1、初始同步:initial sync
2、回滚后追赶:post-rollback catch-up
3、切分块迁移:sharding chunk migrations

local数据库:存放了所有元数据和oplog。用于存储oplog的collection的名称为oplog.rs。

--oplogSize arg:size to use (in MB) for replication oplog. default is 5% of disk space. 指定oplog的大小。默认为磁盘大小的5%.

会进行初始同步的场景:
1、节点没有任何数据时。
2、节点丢失副本复制历史。

初始同步的步骤:
1、克隆所有数据库。
2、应用数据集的所有改变,即复制oplog并应用于本地。
3、为所有collection构建索引。

ReplicaSet安装

准备三台机器,系统版本为CentOS7.3

1、修改Hosts

192.168.135.170         node1
192.168.135.171         node2
192.168.135.169         node3

2、分别安装mongodb

#yum install -y mongodb mongodb-server

3、修改各节点配置文件

#vim /etc/mongod.conf
#bind_ip = 127.0.0.1 		新创建的节点记得修改监听地址,默认只监听127.0.0.1。
replSet = testSet
replIndexPrefetch = all

4、启动各节点mongod服务

#systemctl start mongod
> rs.help() 	查看常用命令
rs.status():{ replSetGetStatus : 1 } checks repl set status. 显示复制集的状态。
rs.initiate():{ replSetInitiate : null } initiates set with default settings. 以默认配置初始化复制集。
rs.conf():get the current configuration object from local.system.replset. 查看当前配置信息。
rs.add(hostportstr):add a new member to the set with default attributes (disconnects). 以默认属性添加一个新成员到集群。
rs.slaveOk():shorthand for db.getMongo().setSlaveOk(). 在从节点上标记从节点为Ok状态。
db.isMaster():check who is primary. 检查谁是主节点。
rs.stepDown([secs]):step down as primary (momentarily) (disconnects). 将主节点降级为从节点,这时会重新选举。
rs.reconfig(cfg):updates the configuration of a running replica set with cfg (disconnects). 更新配置。
rs.addArb(hostportstr):add a new member which is arbiterOnly:true (disconnects). 添加一个新节点为arbiter节点。
rs.remove(hostportstr):remove a host from the replica set (disconnects). 将一个节点从集群中删除。
rs.printReplicationInfo():check oplog size and time range. 查看oplog的大小和起始时间范围。
rs.printSlaveReplicationInfo():check replica set members and replication lag. 查看集群成员的复制延时信息。

5、初始化副本集

> rs.status()
{
	"startupStatus" : 3,
	"info" : "run rs.initiate(...) if not yet done for the set",
	"ok" : 0,
	"errmsg" : "can't get local.system.replset config from self or any seed (EMPTYCONFIG)"
}

> rs.initiate()
{
	"info2" : "no configuration explicitly specified -- making one",
	"me" : "node1:27017",
	"info" : "Config now saved locally.  Should come online in about a minute.",
	"ok" : 1
}

> rs.status()
{
	"set" : "testSet",
	"date" : ISODate("2017-03-11T05:49:18Z"),
	"myState" : 1,
	"members" : [
		{
			"_id" : 0,
			"name" : "node1:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 137,
			"optime" : Timestamp(1489211281, 1),
			"optimeDate" : ISODate("2017-03-11T05:48:01Z"),
			"electionTime" : Timestamp(1489211281, 2),
			"electionDate" : ISODate("2017-03-11T05:48:01Z"),
			"self" : true
		}
	],
	"ok" : 1
}

6、添加新成员至副本集

> rs.add("node2:27017")     添加node2
{ "ok" : 1 }
> rs.add("node3:27017")     添加node3
{ "ok" : 1 }

7、再次查看副本集状态,这时就能看到三个节点了

> rs.status()
{
	"set" : "testSet",
	"date" : ISODate("2017-03-11T06:00:29Z"),
	"myState" : 1,
	"members" : [
		{
			"_id" : 0,
			"name" : "node1:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 808,
			"optime" : Timestamp(1489211964, 1),
			"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
			"electionTime" : Timestamp(1489211281, 2),
			"electionDate" : ISODate("2017-03-11T05:48:01Z"),
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "node2:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 322,
			"optime" : Timestamp(1489211964, 1),
			"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
			"lastHeartbeat" : ISODate("2017-03-11T06:00:28Z"),
			"lastHeartbeatRecv" : ISODate("2017-03-11T06:00:29Z"),
			"pingMs" : 3,
			"syncingTo" : "node1:27017"
		},
		{
			"_id" : 2,
			"name" : "node3:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 65,
			"optime" : Timestamp(1489211964, 1),
			"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
			"lastHeartbeat" : ISODate("2017-03-11T06:00:28Z"),
			"lastHeartbeatRecv" : ISODate("2017-03-11T06:00:28Z"),
			"pingMs" : 5,
			"syncingTo" : "node1:27017"
		}
	],
	"ok" : 1
}

8、分别在各从节点设置节点为Ok状态

> rs.slaveOk()

9、查看副本集配置信息
https://docs.mongodb.com/v2.6/reference/replica-configuration/

> rs.conf()
{
	"_id" : "testSet",
	"version" : 3,
	"members" : [
		{
			"_id" : 0,
			"host" : "node1:27017"
		},
		{
			"_id" : 1,
			"host" : "node2:27017"
		},
		{
			"_id" : 2,
			"host" : "node3:27017"
		}
	]
}

10、将主节点降级为从节点

> rs.stepDown()
> rs.status() 		这里重新选举后,node3成为主节点。
{
	"set" : "testSet",
	"date" : ISODate("2017-03-11T06:40:03Z"),
	"myState" : 2,
	"syncingTo" : "node3:27017",
	"members" : [
		{
			"_id" : 0,
			"name" : "node1:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 3182,
			"optime" : Timestamp(1489211964, 1),
			"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
			"infoMessage" : "syncing to: node3:27017",
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "node2:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 2696,
			"optime" : Timestamp(1489211964, 1),
			"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
			"lastHeartbeat" : ISODate("2017-03-11T06:40:01Z"),
			"lastHeartbeatRecv" : ISODate("2017-03-11T06:40:02Z"),
			"pingMs" : 6,
			"lastHeartbeatMessage" : "syncing to: node1:27017",
			"syncingTo" : "node1:27017"
		},
		{
			"_id" : 2,
			"name" : "node3:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 2439,
			"optime" : Timestamp(1489211964, 1),
			"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
			"lastHeartbeat" : ISODate("2017-03-11T06:40:02Z"),
			"lastHeartbeatRecv" : ISODate("2017-03-11T06:40:03Z"),
			"pingMs" : 2,
			"electionTime" : Timestamp(1489214375, 1),
			"electionDate" : ISODate("2017-03-11T06:39:35Z")
		}
	],
	"ok" : 1
}

11、查看副本集信息,这里会显示oplog大小和起始时间范围。

> db.printReplicationInfo()
configured oplog size:   2464.306884765625MB
log length start to end: 0secs (0hrs)
oplog first event time:  Sat Mar 11 2017 00:59:24 GMT-0500 (EST)
oplog last event time:   Sat Mar 11 2017 00:59:24 GMT-0500 (EST)
now:                     Sat Mar 11 2017 01:46:07 GMT-0500 (EST)

> rs.printReplicationInfo()
configured oplog size:   2464.36328125MB
log length start to end: 6205secs (1.72hrs)
oplog first event time:  Sat Mar 11 2017 13:55:07 GMT+0800 (CST)
oplog last event time:   Sat Mar 11 2017 15:38:32 GMT+0800 (CST)
now:                     Sat Mar 11 2017 15:42:26 GMT+0800 (CST)

> rs.printSlaveReplicationInfo()
source: node1:27017
	syncedTo: Sat Mar 11 2017 15:38:32 GMT+0800 (CST)
	0 secs (0 hrs) behind the primary 
source: node3:27017
	syncedTo: Sat Mar 11 2017 15:38:32 GMT+0800 (CST)
	0 secs (0 hrs) behind the primary
副本集重新选举的条件:
1、心跳信息
2、节点优先级
3、optime
4、网络分区

触发重新选举的场景:
1、新副本集初始化时
2、从节点联系不到主节点时
3、主节点降级时

12、修改节点优先级,只能在主节点上修改
https://docs.mongodb.com/v2.6/tutorial/adjust-replica-set-member-priority/
默认优先级为1,优先级的设定范围为0-1000。

> cfg=rs.conf()
> cfg.members[1].priority = 2
2
> rs.reconfig(cfg) 		这时会重新选举节点2为主节点
2017-03-11T02:38:32.726-0500 DBClientCursor::init call() failed
2017-03-11T02:38:32.796-0500 trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2017-03-11T02:38:32.825-0500 reconnect 127.0.0.1:27017 (127.0.0.1) ok
reconnected to server after rs command (which is normal)

13、将一个从节点转换为arbiter
https://docs.mongodb.com/v2.6/tutorial/convert-secondary-into-arbiter/

a、在主节点remove该从节点
b、将从节点stop
c、清空数据目录
d、启动服务
e、将节点以arbiter的角色添加到副本集
posted @ 2017-03-12 02:56  KeithTt  阅读(3749)  评论(0编辑  收藏  举报