MongoDB 5.0 PSA副本集与分片下默认写关注差异

2022-09-22 11:47:02 浏览数 (1)

接上一篇MongoDB PSA架构痛点以及如何应对有朋友指出,5.0分片集群采用PSA时,出现S宕机时,客户端写入hang,并没有按官方文档描述那样PSA默认写是w:1.我当初只是验证PSA副本集发现与官方描述一致,但并没有验证分片架构.导致存在偏差.

【分析与验证过程】

【验证PSA副本集模式】

1、PSA副本集默认写关注

shard2:PRIMARY> db.adminCommand({getDefaultRWConcern:1})

{

"defaultReadConcern" : {

"level" : "local"

},

"defaultWriteConcernSource" : "implicit",

"defaultReadConcernSource" : "implicit",

"localUpdateWallClockTime" : ISODate("2022-05-17T06:03:42.239Z"),

},

2、验证50 PSA版本默认writeConcern

备注:关闭一个数据节点后写入是否正常.

shard2:PRIMARY> cfg.members[0].stateStr

PRIMARY

shard2:PRIMARY> cfg.members[1].stateStr

(not reachable/healthy)

shard2:PRIMARY> cfg.members[2].stateStr

ARBITER

shard2:PRIMARY> use test

switched to db test

--没有指定writeConcern成功写入

shard2:PRIMARY> db.testDefaultWriteConcern.insert({w:1})

WriteResult({ "nInserted" : 1 })

--指定写入失败,说明默认majority而是官方说w:1

shard2:PRIMARY>db.testDefaultWriteConcern.insert({w:1},{writeConcern:{w:"majority",wtimeout:1000}})

WriteResult({

"nInserted" : 1,

"writeConcernError" : {

"code" : 64,

"codeName" : "WriteConcernFailed",

"errmsg" : "waiting for replication timed out",

"errInfo" : {

"wtimeout" : true,

"writeConcern" : {

"w" : "majority",

"wtimeout" : 1000,

"provenance" : "clientSupplied"

}

}

}

})

【分片使用单个PSA shard来验证来验证默认写关注级别】

1、查看集群信息

mongos> sh.status()

--- Sharding Status ---

shards:

{ "_id" : "shard2",

"host" : "shard2/10.230.10.150:21017,10.230.9.150:21017", "state" : 1,

"topologyTime" : Timestamp(1652772600, 4) }

active mongoses:

"5.0.2" : 1

autosplit:

Currently enabled: yes

databases:

{ "_id" : "config", "primary" : "config", "partitioned" : true }

2、创建分片集合

mongos> sh.enableSharding("xiaoxu")

{

"ok" : 1,

}

mongos> sh.shardCollection("xiaoxu.testDefaultWriteConcern",{_id:"hashed"})

{

"collectionsharded" : "xiaoxu.testDefaultWriteConcern",

"ok" : 1,

}

3、正常情况插入测试数据

备注:不管采用默认writeConcern还是采用w:1或者w:"majority"模式都没有问题

mongos> use xiaoxu

switched to db xiaoxu

mongos> db.testDefaultWriteConcern.insert({_id:1,name:"xiaoxu"})

WriteResult({ "nInserted" : 1 })

mongos>db.testDefaultWriteConcern.insert({_id:2,name:"xiaoxu"},{writeConcern:{w:"majority",wtimeout:1000}})

WriteResult({ "nInserted" : 1 })

mongos>db.testDefaultWriteConcern.insert({_id:3,name:"xiaoxu"},{writeConcern:{w:1}})

WriteResult({ "nInserted" : 1 })

4、模拟PSA副本中S宕机的场景来插入数据

备注:手动关闭从实例

shard2:PRIMARY> cfg.members[0].stateStr

PRIMARY

shard2:PRIMARY> cfg.members[1].stateStr

(not reachable/healthy)

shard2:PRIMARY> cfg.members[2].stateStr

ARBITER

mongos> db.testDefaultWriteConcern.insert({_id:6,name:"xiaoxu"},{w:1})

WriteResult({ "nInserted" : 1 })

mongos>

mongos>

mongos>db.testDefaultWriteConcern.insert({_id:7,name:"xiaoxu"},{w:"majority",wtimeout:10000})

WriteResult({

"nInserted" : 1,

"writeConcernError" : {

"code" : 64,

"codeName" : "WriteConcernFailed",

"errmsg" : "waiting for replication timed out; Error details: { wtimeout: true, writeConcern: { w: "majority", wtimeout: 10000, provenance: "clientSupplied" } } at shard2",

"errInfo" : {

}

}

})

异常:此时没有指定writeConcern,采用默认的行为.此时写入hang住.

mongos> db.testDefaultWriteConcern.insert({_id:8,name:"xiaoxu"})

5、分片下写入数据默认的writeConcern来源哪里?

备注:查询发现defaultWriteConcern是w:majority.这个信息是来自于config.而不是shard层面.目前config是单节点的副本集.尝试改成PSA架构试试?

mongos> db.adminCommand({getDefaultRWConcern:1})

{

"defaultReadConcern" : {

"level" : "local"

},

"defaultWriteConcern" : {

"w" : "majority",

"wtimeout" : 0

},

"defaultWriteConcernSource" : "implicit",

"defaultReadConcernSource" : "implicit",

}

6、尝试把config副本集改成PSA架构

备注:confg副本集中禁止加入仲裁节点.那么config默认是writeConcern就是{w:majority}.

config:PRIMARY> rs.reconfigForPSASet(2, cfg);

Running first reconfig to give member at index 2 { votes: 1, priority: 0 }

{

"ok" : 0,

"errmsg" : "Arbiters are not allowed in replica set configurations being used for config servers",

"code" : 103,

"codeName" : "NewReplicaSetConfigurationIncompatible",

"$gleStats" : {

"lastOpTime" : {

"ts" : Timestamp(1652693376, 3),

"t" : NumberLong(1)

}

7、针对分片集群下DefaultRWConcern相关说明

解释;

1、连接到mongos时没有显式指定writeConcern时,mongos使用全局默认设置,这个全局设置来自config副本集,而不是底层分片,所有底层分片PSA下架构默认writeConcern:{w:1}直接被config副本集全局设置覆盖.因为config不支持仲裁,所以默认是writeConcern:{w:"majority"}

8、5.0 PSA出现S宕机时,为了避免上一篇文章提到问题外.还包括如下:

如果客户端没有指定writeConcern采用默认行为会导致写入hang的情况

应对措施:

1、采用方案2.注意是临时的,等从库恢复及时重置回去,否则当主库宕机,没有办法选出新主,从而影响系统可用性,此时从宕机或者机器挂了,需要及时监控并修改配置,否则可能会影响应用使用.

2、修改config默认writeConcern为w:1虽然能解决写入hang问题,但无法解决底层分片内存压力以及性能下降问题等问题.详细查看上一篇文档说明.

9、修改分片中宕机的实例节点信息来验证写入

shard2:PRIMARY> cfg.members[1].priority=0

0

shard2:PRIMARY> cfg.members[1].votes=0

0

shard2:PRIMARY> rs.reconfig(cfg)

10、再次验证mongos插入数据

备注:经过修改后,不管是否指定writeConcern还是指定majority都可以。

注意:应用此时指定w:2就有问题.

mongos> db.testDefaultWriteConcern.insert({_id:9})

WriteResult({ "nInserted" : 1 })

mongos>db.testDefaultWriteConcern.insert({_id:10},{writeConcern:{w:"majority",wtimeout:1000}})

WriteResult({ "nInserted" : 1 })

总结:至此完成分析PSA架构包括集群下使用PSA分片存在问题以及对应方案,不管怎么应对,都需要注意潜在的影响.例如当单个数据节点宕机或者长延迟时,可以通过程序定时检测节点状态,出现异常时临时将优先级别与投票设置0来避免5.0分片集群下默认多节点写入导致hang或者客户端指定多节点写入hang问题.由此带来一致性问题与高可用性问题需要关注的.

0 人点赞