一、什么是writeConcern ?
writeConcern 决定一个写操作落到多少个节点上才算成功。writeConcern 的取值包括:
1.1 默认行为
1.2 w: "majority"
1.3 w: "all"
1.4 j: true
writeConcern 可以决定写操作到达多少个节点才算成功,journal则定义如何才算成功。取值包括:
二、writeConcern 的意义
对于5个节点的复制集来说,写操作落到多少个节点上才算是安全的?
三、writeConcern 实验
3.1 在复制集测试writeConcern参数
rs0:PRIMARY> db.test.insert( {count: 1}) # 默认
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.test.insert( {count: 1}, {writeConcern: {w: "majority"}}) # 大多数节点
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.test.insert( {count: 1}, {writeConcern: {w: 3 }}) # 三个节点
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.test.insert( {count: 1}, {writeConcern: {w: 4 }}) # 由于集群只有三个节点,所以当要求数据落到4个节点才返回成功时,会报错
WriteResult({
"nInserted" : 1,
"writeConcernError" : {
"code" : 100,
"codeName" : "UnsatisfiableWriteConcern",
"errmsg" : "Not enough data-bearing nodes"
}
})
# 查看插入成功记录
rs0:PRIMARY> db.test.find()
{ "_id" : ObjectId("60cefe0e651d9ab31c945d0c"), "count" : 1 }
{ "_id" : ObjectId("60cefe16651d9ab31c945d0d"), "count" : 1 }
{ "_id" : ObjectId("60cefe1c651d9ab31c945d0e"), "count" : 1 }
{ "_id" : ObjectId("60cefe23651d9ab31c945d0f"), "count" : 1 }
3.2 配置延迟节点,模拟网络延迟(复制延迟)
(1)将副本集节点配置存入conf参数
rs0:PRIMARY> conf=rs.conf()
{
"_id" : "rs0",
"version" : 3,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "10-27-0-224:28017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "10-27-0-224:28018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "10-27-0-224:28019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("60ce02f5209133abd12c1175")
}
}
(2)查看获取的属组信息
rs0:PRIMARY> conf.members
[
{
"_id" : 0,
"host" : "10-27-0-224:28017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "10-27-0-224:28018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "10-27-0-224:28019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
]
(3)设置延迟节点
rs0:PRIMARY> conf.members[2].slaveDelay = 5 # 设置第三个节点延迟5s
5
rs0:PRIMARY> conf.members[2].priority = 0 # 取消第第三个节点参与选举的权利
0
(4)保存配置
rs0:PRIMARY> rs.reconfig(conf)
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1624178758, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1624178758, 1)
}
(5)观察复制延迟下的写入,以及timeout参数
rs0:PRIMARY> db.test.insert( {count: 1}, {writeConcern: {w: 3}})
rs0:PRIMARY> db.test.insert( {count: 1}, {writeConcern: {w: 3, wtimeout:3000 }})
四、注意事项
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。