“Linearizable”读取问题已在 MongoDb 3.4 中引入,以解决“majority”读取问题可能存在的问题。
让我们试着理解“majority”阅读关注的问题,以感受“Linearizable”给我们带来了什么。
假设,我们有一个包含 3 个节点的副本集,看起来像这样:
在哪里,
A 是主要的,
B 是次要的,
C 是次要的
我们还有两个用户 Alice 和 Bob,他们将对位于“users 中的以下文档执行一些操作”集合。
{
"_id": 100234,
"name": "Katelyn"
}
在 T0 时刻:
以下发生,
- Alice 连接到 A(主)并发出以下命令。
db.users.find({"_id":100234}); --> 阅读关注“多数”
输出:
{ "_id" : 100234, "name" : "凯特琳" }
-
B 和 C 意识到 A 已停止响应并开始选举程序。(可能是由于网络分区) .
在 T1 时刻:
以下发生,
- 由于选举过程,B 成为新的主节点。
然而,直到 A 没有被传达或 A 自己意识到它需要将自己降级为次要,它会继续充当主要(这通常是为了虽然时间很短)。
在 T2 时刻:
- Bob 连接到 B(新主节点)并发出以下命令。
db.users.update({"_id":100234}, {$set: {name:"Sansa"} }); --> 与
写关注“多数”。
- Bob 已确认写入。
在 T3 时刻:
- Alice 连接到 A(旧主节点)并发出以下命令。
db.users.find({"_id":100234}); --> 阅读关注“多数”
输出:
{ "_id" : 100234, "name" : "凯特琳" }
即使在发出多数读取关注之后,Alice 也会在此处获取陈旧数据,即 Bob 进行的写入对 Alice 不可见。
因此,“Linearizability”的性质在这种情况下得到了补偿。
线性化的定义:
写入应该是瞬时的。不准确,一旦写
完成,所有后续读取(其中“稍后”由挂钟定义
开始时间)应返回该写入的值或
以后写。一旦读取返回特定值,所有后续读取
应该返回该值或稍后写入的值。
因此,出现了解决方案,即“linearizable”阅读关注点。使用此属性,mongod 检查其主节点并可以看到大多数节点
在发出读取操作的结果之前。
但是,使用此 Read Concern 而非“majority”会降低性能成本,因此这不能替代“majority”读取关注。
关于 writeConcernMajorityJournalDefault 属性,它只是一个副本集配置选项。它接受布尔值。
True 表示,在大多数投票成员写入磁盘日志后,MongoDB 确认写入操作。
False 表示,MongoDB 在大多数投票成员在内存中应用了该操作后,才确认写入操作。
上述属性仅适用于写入关注“majority”且未指定日志标志的情况。