最近云上用户用户遇到一个 sharding 集群性能问题的疑惑,比较有表明性,简单分享一下后端
测试配置
- mongos x 二、shard x 3
- 测试1:集合不开启分片,批量 insert 导入数据,每一个 batch 100 个文档
- 测试2:集合开启分片,随机生成 shardKey,chunk 已提早 split 好,能确保写入均分到3个shard
测试结果
- 测试1:单个 shard cpu 跑满,insert qps 在 6w 左右
- 测试2:3个 shard cpu 跑满,insert qps 在 7w 左右(平均每一个分片2.4w左右)
注:两个测试里,mongos 都不是瓶颈,能力足够网络
从测试结果看,每一个shard都承担 1/3 的负载,的确达到横向扩张的目的,但为啥分片以后,单个shard的能力就降低了呢?若是是这样,sharding的扩展能力如何体现?性能
结果分析
这里核心的问题在于 batch insert 在 mongos 和 mongod 上处理行为的差异测试
- 导入数据时,一次 insert 一条数据,和一次 insert 100 条数据,性能差距是很大的;首先减小了client、server 端之间的网络交互;同时 server 能够将 batch insert 放到一个事务里,下降开销;
- mongos 在收到 batch insert 时,由于一个 batch 里的数据须要根据 shardKey 分布到不一样的shard,因此一个 batch 实际上须要被拆开的;这里 mongos 也作了优化,会尽可能将连续的分布在一个shard上的文档作 batch 发到后端 shard。
- 在集合不开启分片的状况,mongos 收到的 batch 确定是转发给 primary shard,因此转发过去仍是一整个 batch 操做; 而在集合开启分片的状况下,由于用户测试时,shardKey 是随机生成的,基本上整个 batch 被打散成单条操做,逐个日后端 shard 上发送,请求到后端 shard 基本已经彻底没有合并了。
因此在上述测试中,不分片的单个 shard 6w qps、与分片后每一个 shard 2.4w qps,实际上就是请求是否 batch 执行的差异。优化
对应用的影响
从上面的分析能够看出,batch 往分片的集合写入时,由于没法预知数据应该分散到哪一个分片,实际上日后端 shard 写入时,会失去 batch 的效果,但这个批量导入通常发生在数据导入阶段,影响比较小。server
本文做者:张友东
原文连接事务
本文为云栖社区原创内容,未经容许不得转载。文档