多数据中心MongoDB分片集群网络分区下持续写入方案咨询
问题描述
集群架构
现有3个数据中心(实际将扩展至7个),每个数据中心部署以下MongoDB节点:
- 1个Router节点
- 1个Config Server节点
- 分片节点按数据中心分布:
- DataCenter 1
- Shard1Node1 [Primary]
- Shard2Node2 [Secondary]
- Shard3Node2 [Secondary]
- DataCenter 2
- Shard1Node2 [Secondary]
- Shard2Node1 [Primary]
- Shard3Node3 [Secondary]
- DataCenter 3
- Shard1Node3 [Secondary]
- Shard2Node3 [Secondary]
- Shard3Node1 [Primary]
- DataCenter 1
当前配置与核心问题
- 已通过Zone Sharding将写入定向至本地数据中心的Primary节点,读取操作使用本地Secondary节点
- 当单个数据中心与其他DC网络断开时,该DC内的原Primary节点会因3节点副本集失去多数投票而降级为Secondary,拒绝写入请求;需保证断网时仍能读取本地Secondary节点的已同步数据
额外需求
- 任意数据中心断网时,本地应用仍可写入数据,并读取其他DC已同步的最后数据
- 扩展至7个数据中心时,无需为每个新增DC给每个分片额外添加Secondary数据节点
解决方案
1. 调整副本集投票规则,实现网络分区下的Primary保留
针对每个分片的副本集,修改配置以支持区域感知的多数投票:
- 为每个数据中心的分片节点添加区域标签,例如
dc: dc1、dc: dc2 - 配置
settings.minimumMajorityVoteCount参数为2,同时为每个DC的分片节点设置votes: 1,本地仲裁节点(后续添加)也设置votes: 1 - 为对应DC的Primary节点设置更高的
priority(如priority: 2),确保网络恢复后该节点能重新成为Primary - 针对本地写入场景,使用自定义写关注
w: "localMajority"(MongoDB 4.2+支持),断网时无需等待跨DC同步即可完成写入;日常场景保留w: "majority"保证数据一致性
2. 优化副本集节点布局,适配多数据中心扩展
为避免分片数据节点数随DC数量线性增加,采用固定数据节点+本地仲裁节点的布局:
- 每个分片的副本集保留3个跨DC的核心数据节点(1个Primary+2个Secondary),负责全量数据存储与跨DC同步
- 每个新增数据中心仅为每个分片添加1个仲裁节点(Arbiter),仲裁节点仅参与投票、不存储数据,用于在本地网络分区时为对应DC的分片节点提供投票支持,帮助其达到
minimumMajorityVoteCount要求,保持Primary状态 - 此布局下,扩展至7个DC时,每个分片仅需3个数据节点+7个仲裁节点,无需为新增DC添加额外Secondary数据节点
3. 读写偏好与Zone Sharding优化
- 写入操作:保持Zone Sharding配置,将对应DC的分片节点划入本地Zone,确保写入定向到本地Primary;断网时自动降级为
writeConcern: { w: 1, j: true },无需等待跨DC同步即可完成写入 - 读取操作:配置
readPreference: "secondaryPreferred"并指定本地DC的标签(如tagSets: [{ dc: "dc1" }]),断网时自动切换到本地Secondary节点读取已同步数据;若本地无可用Secondary,可降级到读取本地Primary节点
4. Config Server集群高可用优化
将Config Server部署为3节点副本集(跨3个核心DC),同时为每个新增DC添加Config Server仲裁节点,确保Config Server集群在任意单个DC断网时仍能保持可用,避免Router节点无法获取分片配置
内容的提问来源于stack exchange,提问作者Ahmet Burak
相关产品推荐
相关产品推荐

