为何MongoDB分片集群的写入操作仅命中单个分片
MongoDB双分片集群仅单分片处理写入的排查解决方案
常见原因及对应修复方案
- 分片键选择不合理,所有数据落到同一分片的chunk上
这是最常见的触发原因。如果选择的分片键基数过低(比如只有少量可选值,所有文档的分片键值都落在shard1负责的chunk区间),或是使用了升序分片键且集群刚上线还未触发chunk分裂、迁移,所有新写入都会落到默认初始分片shard1上。
排查方式:连接mongos路由节点执行sh.status()查看chunk分布,确认是否所有chunk都位于shard1。
修复方案:更换基数更高、值分布更均匀的分片键;如果是升序分片键的初始阶段问题,等待数据量增长触发chunk自动迁移即可,也可以手动触发chunk分裂加快均衡进度。 - 分片集群balancer进程未正常运行
balancer负责在多个分片之间迁移chunk均衡数据分布,如果balancer被手动关闭或是运行异常,新产生的chunk不会被迁移到shard2,就会出现只有shard1处理写入的情况。
排查方式:执行sh.getBalancerState()确认balancer是否处于开启状态,执行sh.isBalancerRunning()确认进程是否在正常运行。
修复方案:如果balancer被关闭,执行sh.startBalancer()开启即可;如果运行异常,排查mongos节点、config server节点的日志定位故障点。 - shard2未被正确加入集群或是处于不可用状态
虽然部署了shard2副本集,但如果添加分片的操作未成功执行,或是shard2的主节点无法被mongos、config server正常访问,集群会自动把所有写入都路由到可用的shard1上。
排查方式:执行sh.status()查看分片列表,确认shard2在列表中且状态正常;登录shard2主节点检查服务是否正常运行,同时测试从mongos节点能否正常连接shard2的服务端口。
修复方案:如果未完成分片添加,执行sh.addShard("shard2副本集名/主节点地址:端口,从节点地址:端口")完成配置;如果是网络连通问题,修复对应服务器的防火墙、安全组规则,确保集群内部服务端口互通。 - 写入操作指定的分片键值全部命中shard1负责区间
如果业务写入语句都指定了同一个分片键值,或是所有分片键值都落在shard1负责的chunk区间,路由层会正常把所有写入都转发到shard1,不属于集群故障。
排查方式:开启mongos的慢日志查看写入语句的分片键值分布,确认是否所有值都在shard1的负责区间内。
修复方案:如果业务逻辑允许,调整写入的分片键值分布,让数据均匀落到两个分片上即可。
验证方法
完成对应修复操作后,写入一批分片键值分布均匀的测试数据,通过htop观测两个分片主节点的资源占用,同时执行sh.status()确认chunk已经均匀分布在两个分片上,即可确认问题修复。
内容的提问来源于stack exchange,提问作者21bn
相关产品推荐
相关产品推荐

