面试题答案
一键面试insertMany操作在MongoDB分布式集群中的实现及数据传播
- 副本集:
- 主节点操作:当在副本集环境下执行
insertMany
操作时,客户端请求首先发送到主节点(Primary)。主节点会将这些文档按顺序写入其 oplog(操作日志)。oplog 记录了主节点上所有的写操作。 - 从节点同步:从节点(Secondary)会定期轮询主节点的 oplog,获取新的操作记录。从节点按照 oplog 中的记录顺序,在本地重现这些写操作,从而保持与主节点的数据同步。例如,如果主节点使用
insertMany
插入了10个文档,从节点会按照 oplog 里的记录依次插入这10个文档。
- 主节点操作:当在副本集环境下执行
- 分片集群:
- 路由节点(mongos):客户端的
insertMany
请求首先到达路由节点(mongos)。mongos 根据文档中的分片键计算出每个文档应该被路由到的具体分片(Shard)。 - 分片节点(Shard):mongos 将文档转发到相应的分片节点。每个分片节点接收到文档后,在本节点内执行插入操作。如果该分片节点是副本集结构,插入操作在本副本集内的传播过程与上述副本集的情况类似,先写入主节点 oplog,再同步到从节点。
- 路由节点(mongos):客户端的
确保插入操作一致性
- 网络分区:
- 副本集:在网络分区发生时,副本集可能会分裂成多个子集。如果原主节点所在子集无法与大多数节点通信,根据选举机制,剩余节点中的一个会被选举为新的主节点。原主节点会变为从节点。新主节点继续处理写操作,原主节点重新连接后,会通过 oplog 同步错过的写操作,以保证数据最终一致性。
- 分片集群:网络分区可能导致部分分片与 mongos 断开连接。mongos 会检测到连接异常,对于无法连接的分片,暂时停止向其发送写请求。当网络恢复后,分片会与 mongos 重新建立连接,mongos 会继续向其发送未完成的写请求,确保数据最终一致性。
- 节点故障:
- 副本集:如果主节点发生故障,副本集内会触发选举,从节点中符合条件的会被选举为新的主节点。原主节点故障恢复后,会作为从节点加入副本集,并通过 oplog 同步在其故障期间产生的写操作,保证数据一致性。
- 分片集群:如果某个分片节点故障,mongos 会检测到并停止向该分片发送写请求。当故障分片恢复后,mongos 会重新向其发送请求。如果分片节点是副本集结构,内部的一致性恢复机制(如从节点选举、oplog 同步等)会保证本分片内的数据一致性。
保证事务原子性
- 多文档事务(MongoDB 4.0+):在副本集或分片集群环境下,MongoDB 支持多文档事务。对于
insertMany
操作,如果包含在事务中,MongoDB 会使用两阶段提交(2PC)协议。- 准备阶段:主节点(或分片主节点)会协调事务涉及的所有节点,每个节点会在本地准备事务,例如将插入操作写入预写日志(WAL),但不提交。
- 提交阶段:如果所有节点准备成功,主节点会发送提交指令,各节点完成事务提交。如果有任何节点准备失败,主节点会发送回滚指令,所有节点回滚事务,保证事务的原子性。例如在一个跨分片的
insertMany
事务中,所有涉及的分片节点都准备好插入操作后,才会统一提交,否则全部回滚。