我想了解 MongoDB 提供什么保证(如果有的话),因为它与在 Primary 永久或暂时失败的场景中的数据持久性有关,或者当它在网络级别与副本集的其余部分分离时。
我理解 w:1 写关注会发生什么。我理解日记的作用。
我不明白 MongoDB 如何决定在选择新主数据库时保留哪些写入以及丢弃哪些写入。在 4 节点(+仲裁器)集群中,N1 为主节点,N2、N3、N4 为辅助节点,在这种情况下:
问题:
首先介绍一下背景:
mongodb 副本集使用操作日志进行复制。主节点的每次写入都会附加到 oplog。
每个辅助节点查询其同步源以获取 oplog 条目,并批量检索和应用它们。
Oplog 条目是幂等的,必须按顺序应用。
在将条目写入 oplog 本身之前,它们首先被写入日志。
如果节点在应用批处理时崩溃,从日志中重放整个批处理是安全的,因为每个条目都是幂等的。
成员相互报告他们最近应用的 oplog 事件的标识符。
由于 oplog 事件必须按顺序应用,这意味着每个节点都在报告条目之前应用了所有条目,之后没有应用。
在 5 个节点的副本集中,大多数是 3 个节点。主w:majority
节点不会向客户端/应用程序确认写入已完成,直到大多数节点报告其 oplog 已到达或通过添加写入的点。
副本集中的每个节点都监视其他每个成员。
如果主要节点意识到它无法与大多数投票节点通信,它将降级到次要节点。
如果辅助节点在几秒钟内(默认为 10 秒)与主节点之间没有任何通信,它将要求进行选举。
发起选举的节点会向每个副本集成员征求投票。
每个成员通常都会投“是”,他们可能会投“否”的几个原因是:
如果候选节点收到足够多的“是”票以构成副本集中的大多数投票节点,则它将转换为主节点并接受写入。
每次选举都会增加term
副本集的值。如果主机从包含高术语的其他节点接收到的心跳或其他消息,则它立即缩至辅助。
{w:majority, j:true} 写入命中主节点。
主要将:
假设主要的 oplog 现在包含:
|时间 | 操作| |-----|------------| | T1 | 创建收藏| | T2 | 创建索引 | | T3 | 插入文档 1| | T4 | 插入文档 2| | T5 | 更新文档 1| | T6 | 插入文档 3|
我将使用 T5 的更新作为w:majority
写入。
次要轮询更改,主要等待多数人确认。
N1 是主要的,N5 是仲裁者。在 T5 写入之前,其余节点显示以下最近应用的 oplog 事件:
N2:T4
N3:T4
N4:T2
N2 确认更改。
最近应用的 oplog 事件现在是:
N2:T5
N3:T4
N4:T3
N3 已收到更改并正在应用它。
这意味着 N3 不会向任何其他节点报告新的上次应用 oplog 时间,并且主节点仍然不会向提交写入的应用进程确认成功或失败。
主要出现故障
在主要失败之前的那一刻,每个成员最后应用的 optime 是:
N1:T6
N2:T5
N3:T4
N4:T3
N5:不适用
N3 无法向 Primary 确认它已应用更改。
在这种情况下是合理的。
选举是被迫的。
在适当的超时后,一个或多个辅助节点将要求进行选举。
让我们假设 N3 实际上确实完成了应用 T5 的操作。
如果 N4 恰好是第一个超时的人,它将要求进行选举,并要求所有成员投票。投票结果如下:
N4:是(总是为自己投票)
N5:否 - 我可以看到一个节点的 oplog 事件比你的更新
N3:否 - 我有一个比你最近的 oplog 事件
N2:否 - 同上
此时N2或N3将参加下一次选举,选票如下:
候选人 N3:是 - 自己
N5:是 - 你有最近的事件
N4:是 - 你比我更新
N2:是 - 你至少和我一样更新
本次选举成功,节点过渡到primary。
如果 N3 应用了来自 T5 的事件,无论它是否已报告给主节点,都可能发生此事件序列。由于所有节点都监视所有其他节点,因此 N3 将向 N2、N4 和 N5 报告。
请注意,如果 #4 没有发生,N3 仍将处于 T4,并且不会被选中,因为 N2 发生了最近的事件。
在任何一种情况下,任何参与选举的次要应用的最新事件都将被保留。
当 N1 恢复并尝试重新加入副本集时,新主节点上的 oplog 很可能已超出 T6。由于当前主节点不知道 T6 的写操作,并且前主节点不能成为辅助节点,除非它可以重放当前主节点的 oplog 条目,节点比较它们的 oplog 历史,直到找到一个共同点。
在这种情况下,这将是 T5。
然后,前一个主服务器回滚 T6 处的操作所做的更改,并将回滚的数据写入本地磁盘文件,以便稍后在必要时恢复。它从新的主节点请求 T5 之后的 oplog 条目,并开始作为辅助节点进行复制。
在这种情况下,唯一丢失的写入是由主节点处理但未复制到任何其他节点的写入。
如果 Primary 已确认写入,并且 N2 复制了写入已被多数人确认的事实,结果是否不同?如果 N2 和 N3 都复制了写入被多数人确认的事实,结果是否不同?
这个事实实际上不需要复制。每个节点都在监视其他节点,因此每个辅助节点都将清楚地知道大多数副本集已经看到了哪些 oplog 条目,而不会被告知。
唯一的区别是,如果 N3 也向主节点报告它已复制操作,则主节点可以向应用程序报告多数写入成功。
如果:
在这种情况下,N1 会意识到它无法联系大多数副本集,并会下台。
如果 N1 或 N2 试图要求选举,他们将无法获得所需的 3 票
由于落后,N4仍然不会被选为N3
当 N3 要求选举时,N4 和 N5 都会投“是”,因此 N3 将成为主要的。
这意味着当网络分区被修复时,N1 和 N2 都会发现它们有当前主节点不知道的写入。
在这种情况下,T5 和 T6 写入都将回滚。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句