MongoDB replication

注:本文基于MongoDB 4.2编写

1 关于replication

MongoDB的副本集能保证数据库服务的冗余性和高可用,这也是生产环境的必要配置。每个副本集都保存相同的数据,保证主节点异常时能接替主节点继续提供服务。

2 搭建集群

我们用3台机器搭建一主二从的集群,MongoDB的安装参考——MongoDB的安装及连接

在三台机器上都安装好MongoDB,然后配置保持一致,

[root@master ~]# grep -vE "^$|^#" /etc/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: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

3 设置replication

在每台机器的/etc/mongod.conf里增加以下section,也就是指定replication名字,切记这名字在集群host上一定要保持一致

replication:
  replSetName: mdbA

添加完记得重启mongod服务,

systemctl restart mongod

4 replication相关操作

这时候我们连接上数据库,查看replication情况,

> rs.status()
{
	"ok" : 0,
	"errmsg" : "no replset config has been received",
	"code" : 94,
	"codeName" : "NotYetInitialized"
}

可见此时并没有初始化

4.1 初始化replication

我们选择需要作为主节点的机器上登录数据库,初始化replication,

> rs.initiate({_id:'mdbA',members:[{_id:1,host:'192.168.0.110:27017'}]})
{ "ok" : 1 }

其中mdbA就是我们设置的replication的名字,192.168.0.110就是本机,也就是主节点。

这时我们再查看副本集状态,就能看到我们设置的主节点。

mdbA:OTHER> rs.status()
{
	"set" : "mdbA",
	"date" : ISODate("2022-03-12T08:13:29.473Z"),
	"myState" : 1,
	"term" : NumberLong(1),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"majorityVoteCount" : 1,
	"writeMajorityCount" : 1,
	...
	"members" : [
		{
			"_id" : 1,
			"name" : "192.168.0.110:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 920,
			"optime" : {
				"ts" : Timestamp(1647072799, 8),
				"t" : NumberLong(1)
			},
			...
		}
	],
	...
}

4.2 添加replication

将其余两台host也添加到副本集里,

mdbA:PRIMARY> rs.add( { host: "192.168.0.111:27017", priority: 0, votes: 0 } )
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1647074399, 2),
		"signature" : {
			"hash" : BinData(0,"Wq3jZwDyUyLirf7YW+AAwH6HQYs="),
			"keyId" : NumberLong("7074123805836181509")
		}
	},
	"operationTime" : Timestamp(1647074399, 2)
}
mdbA:PRIMARY> rs.add( { host: "192.168.0.112:27017", priority: 0, votes: 0 } )
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1647074419, 2),
		"signature" : {
			"hash" : BinData(0,"sECwHoLvoYaS0LNKX6GlAFS9nDA="),
			"keyId" : NumberLong("7074123805836181509")
		}
	},
	"operationTime" : Timestamp(1647074419, 2)
}

这时查看replication状态就能看到三台host了,

mdbA:PRIMARY> rs.status()
{
	"set" : "mdbA",
	"date" : ISODate("2022-03-12T09:34:44.767Z"),
	"myState" : 1,
	"term" : NumberLong(2),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	...
	"members" : [
		{
			"_id" : 1,
			"name" : "192.168.0.110:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 94,
			...
		},
		{
			"_id" : 2,
			"name" : "192.168.0.111:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 92,
			...
		},
		{
			"_id" : 3,
			"name" : "192.168.0.112:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 92,
			...
		}
	],
	...
}

有一点要注意的是,我添加replication时,设置node的priority和votes都是0,也就说它们并没有选主的权限。这是因为,从节点初始化和同步数据需要一段时间,如果刚好在此时发生选主,如果这些还在同步初始化的节点有投票权,就会有可能无法选主成功。

因此我们开始时将这些新加的node设置无投票权,等到初始化完成,节点变成secondary,再将priority和votes修改为预期值,

mdbA:PRIMARY> var cfg=rs.conf()
mdbA:PRIMARY> cfg.members[1].votes=1
1
mdbA:PRIMARY> cfg.members[1].priority=1
1
mdbA:PRIMARY> rs.reconfig(cfg)
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1647078561, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1647078561, 1)
}

这时再查看节点vote和priority,可以看到已经和primary一致,

mdbA:PRIMARY> rs.conf()
{
	"_id" : "mdbA",
	"version" : 17,
	"protocolVersion" : NumberLong(1),
	"writeConcernMajorityJournalDefault" : true,
	"members" : [
		{
			"_id" : 1,
			"host" : "192.168.0.110:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			...
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "192.168.0.111:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			...
			"votes" : 1
		},
		{
			"_id" : 3,
			"host" : "192.168.0.112:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			...
			"votes" : 1
		}
	],
	...
}

4.3 删除replication

mdbA:PRIMARY> rs.remove("192.168.0.112:27017")
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1647077843, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1647077843, 1)
}

4.4 强制重新选primary

当我们需要对primary升级时,就需要将主节点切换至其他节点

mdbA:PRIMARY> rs.stepDown()
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1647077892, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1647077892, 1)
}

切换后,再查看副本集状态,可以看到primary已经跑到另一台机器,

mdbA:SECONDARY> rs.status()
{
	"set" : "mdbA",
	...
	"members" : [
		{
			"_id" : 1,
			"name" : "192.168.0.110:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 314,
			...
		},
		{
			"_id" : 2,
			"name" : "192.168.0.111:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 439,
			...
		}
	],
	...
}


参考文档:

  1. https://docs.mongodb.com/v4.2/replication/
  2. https://docs.mongodb.com/v4.2/tutorial/expand-replica-set/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值