micro-sharding性能评测

在日常的OLTP型应用中,绝大部分时候我们都会通过索引来优化查询和排序的速度。但在某些特定的OLAP场景下,索引可能并不能帮上多少忙。本文将讨论在这些特定场景下利用micro-sharding来优化这些查询,以及优化后带来的性能提升和需要注意的问题。

警告:micro-sharding只在本文讨论的特定场合下适用,滥用或者错误地使用micro-sharding不旦达不到预期目标,更有可能造成性能下降。实际使用时请确保对micro-sharding有充分的理解并做好测试。

基本概念

什么是micro-sharding?

简单地说,micro-sharding就是在一台服务器上安装多于1个分片实例(通常是每个CPU核部署1个分片实例)的分片部署方式。

为什么需要micro-sharding?

在某些场景(特别是OLAP)场景下,我们需要更多的运算能力,而不太在意时间的消耗。查询的优化重点变为如何优化利用更多的运算资源。micro-sharding在这样的场景中可以更加充分地发挥MongoDB的运算能力而加速分析的过程。

典型应用场景

micro-sharding的典型应用场景是在OLAP下,对时间要求不敏感,需要大量的运算资源时。满足这样条件的场景包括但不限于:
– 参与运算的条件字段太多无法让查询有效命中索引时
– 对大量数据进行分析,命中索引与否无关紧要时
通常OLTP型应用中,MongoDB并非是一个CPU使用大户。其背后的原因大部分时候是因为索引在起作用。因此在索引不起作用或不能完全起作用的场景下,都可以把micro-sharding作为一个解决方案来考虑。它本质上是在把原本不会并行的操作(如aggregation,排序)并行化,从而充分使用运算资源来缩短运算时间,更加快速得到结果。
当然micro-sharding也并不是完全与索引矛盾的存在,很多时候还是可以从索引中受益的。举个例子,可以通过索引预处理出某个时间段的数据,再利用micro-sharding的运算能力分析这些数据;或者更一般的说,利用索引进行预处理缩小数据量,再使用micro-sharding处理剩下的工作。

实践

为了验证micro-sharding能带来多少性能收益,我们做一次实际的测试来比较一下micro-sharding到底能够带来多少性能提升。

硬件

选用AWS上的EC2结点m4.2xlarge
– CPU:8核
– 内存:32G
– 硬盘:50G SSD

集群架构

简单起见我们选择了3台EC2结点作为3个分片,每个分片的复制集均只有一个结点。
警告:实际生产环境中不要使用单结点复制集!

注意事项

  1. 默认情况下WT引擎使用系统内存的60%或1G作为缓存,因此多个实例位于一台服务器上时可能发生内存争抢的问题,需要配置好缓存大小,保证内存足够。
  2. 本例中内存大小足够容纳所有数据,所以不用考虑与磁盘的数据交换问题。实际情况中可能出现内存不足的情况,此时需要考虑文件系统缓存(压缩)和WT缓存(非压缩)的交换问题,如有可能使数据在压缩状态下容纳进文件系统缓存,也是不错的选择。实在无法容纳的情况下,则要考虑磁盘交换问题,此时磁盘有可能成为整个系统的瓶颈,整个性能曲线表现则可能与本测试中的表现不符。
  3. 为系统进程留下足够的CPU和内存。通常留1-2个CPU和少量内存即可。考虑使用cgroup或taskset控制整个mongodb的CPU使用。

测试方法

使用NodeJS和Apache JMeter模拟数据并进行全数据排序。本测试中使用的数据满足以下条件:
– 约1000万数据
– 单个文档大小约2.5k
– 片键选择为{_id: "hashed"}
评测方法:
– 计时时间为从操作开始到返回第一条结果集记录为止
– 在3台服务器上分别创建3片、6片、9片……24片,测试返回结果所需时间
– 比较片数不同的情况下返回结果集所需要的时间
– 比较使用WT引擎和全内存引擎效率差异
测试所使用的源代码和JMeter配置文件已放到我的Github上。

测试结果

片数 平均响应时间(秒) 平均响应时间(内存引擎,秒) 理论每片文档% 内存引擎提升%
3 shards 137.258 114.759 33.33333333 16.39%
6 shards 86.638 75.999 16.66666667 12.28%
9 shards 55.48 51.19 11.11111111 7.73%
12 shards 43.773 38.094 8.333333333 12.97%
15 shards 37.019 35.761 6.666666667 3.40%
18 shards 33.977 28.914 5.555555556 14.90%
21 shards 32.191 27.9 4.761904762 13.33%
24 shards 29.124 25.433 4.166666667 12.67%

测试结果

结论

  1. 排序所需时间和片数基本保持反比关系。
  2. 去掉一个最高分和最低分,内存引擎较普通引擎在排序效率上平均有12.6%的提升。