面试题答案
一键面试网络分区检测
- 心跳机制:MongoDB副本集成员之间通过心跳(Heartbeat)机制保持定期通信。副本集内每个成员每隔一段时间(默认2秒)就会向其他成员发送心跳消息。如果某个成员在一定时间(默认10秒)内没有收到其他成员的心跳响应,就会标记该成员为不可达。这是检测网络分区的基础手段。
- 仲裁节点:仲裁节点不存储数据,主要用于投票。在网络分区时,仲裁节点可以帮助判断哪个子集能够成为主节点。仲裁节点与其他成员保持心跳连接,通过心跳来感知成员的可达性。
保障数据一致性的措施
- 多数投票原则:MongoDB副本集采用多数投票(Majority Vote)来决定主节点。在正常情况下,主节点需要获得副本集中大多数成员(超过一半)的认可才能维持其角色。当网络分区发生时,只有拥有大多数成员的子集才有资格选举出新的主节点。例如,一个包含5个成员(包括仲裁节点)的副本集,至少需要3个成员达成一致才能选举出主节点。这样可以确保新选举出的主节点所在的子集包含了最新的数据,从而保障数据一致性。
- 回滚机制:如果在网络分区期间,不同子集的节点各自进行了写操作。当网络恢复后,MongoDB会进行数据回滚。具体来说,新选举出的主节点会将其他节点的数据同步到与自己一致的状态。对于那些在旧主节点上进行但未被新主节点认可的写操作,会被回滚。例如,假设网络分区后,子集A中的旧主节点接收了一些写操作,而子集B中的节点选举出了新主节点。网络恢复后,子集A中的旧主节点会将数据回滚到与新主节点一致的状态,以保证整个副本集的数据一致性。
不同节点角色在网络分区过程中的行为
- 主节点(Primary):
- 网络分区发生时:如果主节点发现自己与大多数成员失去连接(无法收到多数成员的心跳响应),它会主动降级为从节点(Secondary)。这是为了避免出现多个主节点导致的数据冲突。例如,在一个5成员副本集中,主节点若与3个及以上成员失去联系,就会自动降级。
- 网络恢复时:如果原主节点所在子集不是拥有多数成员的子集,那么它需要从新选举出的主节点同步数据,进行回滚操作,以保证数据一致性。
- 从节点(Secondary):
- 网络分区发生时:从节点如果发现与主节点失去连接,会尝试寻找新的主节点。如果所在子集拥有多数成员,会参与选举新主节点的过程。在选举过程中,从节点会根据自身保存的数据版本等信息,投票给数据最“新”(拥有最高oplog timestamp)的节点。
- 网络恢复时:从节点会与新主节点同步数据,确保自身数据与新主节点一致。如果在网络分区期间从节点有本地写操作(这种情况很少见,一般写操作都发往主节点),也需要进行回滚操作。
- 仲裁节点(Arbiter):
- 网络分区发生时:仲裁节点不存储数据,主要作用是参与投票。在网络分区情况下,仲裁节点会根据心跳判断各成员的可达性,并将投票权投给所在子集拥有多数成员的一方,帮助选出新的主节点。
- 网络恢复时:仲裁节点继续参与副本集的投票过程,保障副本集选举机制的正常运行,以维护数据一致性。