对于集群方式部署的实例,常见Shard间负载不均衡,一般有如下原因:没有做分片,片键选择不正确,不做chunk预置,shard间均衡速度低于数据插入速度等。
排查方法
步骤 1 通过客户端连接数据库。
步骤 2 执行如下命令,查看分片信息。
mongos> sh.status()
\--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("60f9d67ad4876dd0fe01af84")
}
shards:
{ "_id" : "shard_1", "host" : "shard_1/172.16.51.249:8637,172.16.63.156:8637", "state" : 1 }
{ "_id" : "shard_2", "host" : "shard_2/172.16.12.98:8637,172.16.53.36:8637", "state" : 1 }
active mongoses:
"4.0.3" : 2
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: yes
Collections with active migrations:
test.coll started at Wed Jul 28 2021 11:40:41 GMT+0000 (UTC)
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
300 : Success
databases:
{ "_id" : "test", "primary" : "shard_2", "partitioned" : true, "version" : { "uuid" : UUID("d612d134-a499-4428-ab21-b53e8f866f67"), "lastMod" : 1 } }
test.coll
shard key: { "_id" : "hashed" }
unique: false
balancing: true
chunks:
shard_1 20
shard_2 20
- “databases”中列出的所有数据库都是通过enableSharding开放了分片的库。
- “test.coll”表示开启分片的namespace信息,其中test为集合所在的库名,coll为开启分片的集合名。
- “shard key”表示前面集合的分片键,分片方式“_id : hashed”表示通过_id进行哈希分片,如果是“_id : -1”,则代表通过_id的范围进行分片。
- “chunks”代表分片的分布情况。
步骤 3 根据步骤2查询出的结果,分析分片信息。
- 如果业务性能存在瓶颈的数据库和集合,在上述“databases”以及子项中不存在,则说明业务集合没有进行分片。对于集群来说这意味着业务只有一个Shard承载,没有应用DDS的水平扩展能力。
此场景下可以通过如下的命令开启分片,充分发挥实例的水平扩展能力。
mongos> sh.enableSharding("<database>")
mongos> use admin
mongos> db.runCommand({shardcollection:"<database>.<collection>",key:{"keyname":<value> }})
- 如果“shardKey”分片片键选择不合理,也会导致负载不均衡。典型场景有业务热点数据分布在某个范围内,而分片的片键选择范围分片的方式,那么可能会出现热点数据所在的chunk对应的Shard负载会明显的高于其他Shard,最终导致整体性能出现瓶颈。
此场景下可以通过重新设计片键的分布方式来达到目标,比如将范围分片修改为哈希分片。
mongos> db.runCommand({shardcollection:"<database>.<collection>",key:{"keyname":<value> }})
说明
一个集合选择了分片方式,则不能在原集合上随时修改。所在集合在设计阶段需要充分考虑分片方式。
更多关于设置数据分片的内容请参见设置数据分片以充分利用分片性能。
- 如果存在集中大批量的插入数据的场景,数据量超过单shard承载能力的话,可能会出现Balance速度赶不上插入速度,导致主shard存储空间占用率过高。
此场景可以使用sar命令查看服务器网络连接情况,分析每个网卡的传输量和是否达到传输上限。
sar -n DEV 1 //1为间隔时间
Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
Average: lo 1926.94 1926.94 25573.92 25573.92 0.00 0.00 0.00 0.00
Average: A1-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: A1-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: NIC0 5.17 1.48 0.44 0.92 0.00 0.00 0.00 0.00
Average: NIC1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: A0-0 8173.06 92420.66 97102.22 133305.09 0.00 0.00 0.00 0.00
Average: A0-1 11431.37 9373.06 156950.45 494.40 0.00 0.00 0.00 0.00
Average: B3-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: B3-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
说明
“rxkB/s”为每秒接收的kB数。
“txkB/s”为每秒发送的kB数。
检查完后,按“Ctrl+Z”键退出查看。
对于网络过高的情况,建议对MQL语句进行分析,优化思路,降低带宽消耗,提升规格扩大网络吞吐能力。
- 建议排查业务是否存在分片集合的情况消息中未携带ShardKey的情况,此场景下请求消息会进行广播,增加带宽消耗。
- 控制客户端并发线程数,降低网络带宽流量。
- 以上操作无法解决问题时,请及时提升实例规格,高规格节点对应更高网络吞吐能力的虚拟机。