0
点赞
收藏
分享

微信扫一扫

Mongodb中PSD延迟节点架构的坑

修炼之士 2022-06-23 阅读 46

延迟节点介绍

延迟节点反应的是数据库在较早时刻的状态,比如一个配置了延迟时间为3600秒的延迟节点,那么这个延迟节点的数据就是primary一个小时之前的状态。延迟节点存在的意义主要是解决应用层面数据错误的问题,假设管理员对数据库做了一个误操作,如果数据是时时传输的话,那么这个误操作立刻就会被备库同步,这样就导致了备库数据的损坏。而延迟节点就可以解决这样的问题,因为这个误操作需要等待一个延迟时间才能同步到备库。

延迟节点的要求:

  • 必须是优先级为0,因为延迟节点的延迟属性,很显然它不具备成为主库的条件。
  • 必须配置掩藏属性,因为要始终防止应用程序查看和查询延迟成员。
  • 配置投票属性为0可以提高数据库性能


PSD架构中的隐患

在一个PSD(Primary-Secondary-Delay)的架构中,存一个问题,就是这个Delay节点的votes配置到底是应该配置为0还是1的问题。先看看文档中的说明:

Mongodb中PSD延迟节点架构的坑_数据库

在文档中提到,需要确保Delay的成员配置为无投票权也就是votes为0的情况,这个很容易理解,因为在Secondary宕机的情况下主节点的写入需要等待延迟节点的写入,如果延迟节点配置了10分钟的延迟,那么就需要等待10min才能确认写请求(majority)。但是,如果将Delay的votes配置为非零,那么又会导致另外一个问题,看上去的3节点实际上只有2个节点具有投票权,那么在主库或者备库任何节点宕机的时候,都会导致集群无法选主的情况,那么就造成了集群不可写入的情况。

验证

试验拓扑如下

角色

端口

DBPath

Primary

27017

/mongodb/data/rs/db1

Secondary

27018

/mongodb/data/rs/db2

Delay

27019

/mongodb/data/rs/db3

创建副本集

a) 使用如下参数启动3个mongodb实例

[root@vm002 ~]# cat /etc/mongod_1.conf 
storage:
dbPath: "/mongodb/data/rs/db1"
systemLog:
destination: file
path: "/mongodb/log/rs/dblog1/mongo1.log"
logAppend: true
net:
port: "27017"
bindIp: localhost,vm002
processManagement:
fork: true
security:
keyFile: /mongodb/pki/myrp-keyfile
replication:
replSetName: rs0

[root@vm002 ~]# cat /etc/mongod_2.conf
略 <---修改路径即可
[root@vm002 ~]# cat /etc/mongod_2.conf
略 <---修改路径即可

b) 修改db3为延迟节点

cfg=rs.conf()
db3的编号为_id=2
{
"_id" : 2,
"host" : "vm002:27019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {

},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
}

--根据文档中的要求,延迟节点的优先级为0,同时配置掩藏
cfg.members[2].priority=0
cfg.members[2].hidden=true
cfg.members[2].secondaryDelaySecs=20
rs.reconf(cfg)

--当前配置如下
当前配置如下:

{
"_id" : 0,
"host" : "vm002:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {

},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "vm002:27018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {

},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "vm002:27019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : true, <---掩藏
"priority" : 0, <---优先级为0
"tags" : {

},
"secondaryDelaySecs" : NumberLong(20), <---20秒延迟
"votes" : 1
}
]

测试验证1

a) 确认延迟节点生效

主库执行insert操作,预期db2能立刻同步,db3延迟30秒同步
rs0:PRIMARY> db.abc.insert(
... { a:'test' },
... { writeConcern: { w: "majority", wtimeout: 15000 } }
... )
WriteResult({ "nInserted" : 1 })

--db2立刻能查看
rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> db.abc.find()
{ "_id" : ObjectId("62b12b904f96ba620b6307e9"), "a" : 1 }

--db3延迟20秒能查看
rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> db.abc.find()
{ "_id" : ObjectId("62b12b904f96ba620b6307e9"), "a" : 1 }

b) 停止db2

mongod --shutdown -f /etc/mongod_2.conf
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2022-06-21T03:33:47.213Z"),
"myState" : 1,
"term" : NumberLong(2),
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2, <---因为3个节点都有votes,所以majority依然为2
"votingMembersCount" : 3,
"writableVotingMembersCount" : 3,
...
}

c) 再次验证写入

rs0:PRIMARY> db.abc.insert(     { a:'test' },     { writeConcern: { w: "majority", wtimeout: 15000 } } )


WriteResult({
"nInserted" : 1,
"writeConcernError" : {
"code" : 64,
"codeName" : "WriteConcernFailed",
"errmsg" : "waiting for replication timed out",
"errInfo" : {
"wtimeout" : true,
"writeConcern" : {
"w" : "majority",
"wtimeout" : 15000,
"provenance" : "clientSupplied"
}
}
}
})

此时就发现主库的写入会被hang住,因为majority写入需要获取2票,因为延迟节点的特性,需要等待20秒之后才能返回写入的确认信息,这个时候就会造成主库写入的等待。需要注意的是,虽然收到了timeout的错误,对主库的写入依然是成功的,报错信息只是提示等待复制同步的超时。这里就证明了延迟节点配置为非0的确会有延迟问题

测试验证2

调整延迟节点votes为0

rs0:PRIMARY> rs.conf()
...
{
"_id" : 2,
"host" : "vm002:27019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : true,
"priority" : 0,
"tags" : {

},
"secondaryDelaySecs" : NumberLong(20),
"votes" : 0 <---当前votes为0
}
...

在延迟节点votes属性为0的情况下,我们直接关闭Secondary。

这个时候就会发现,剩下的两个成员都是Secondary,集群中无法选Primary了。

Mongodb中PSD延迟节点架构的坑_数据库_02

Mongodb中PSD延迟节点架构的坑_数据_03

结论以及处理方式

在PSD的架构中的确不能解决高可用的问题,如果要解决高可用问题,个人觉得可以在增加一个仲裁节点,这也是在官方文档中描述三节点副本集的时候只提供了PSA和PSS架构的原因。




举报

相关推荐

0 条评论