MongoDB·最佳实践·count不准原因分析

  • 时间:
  • 浏览:0
  • 来源:大发5分6合_大发5分6合官方

也假如有一天说,MongoDB4.0分片集群模式下,针对不带谓词条件的全表count操作的返回结果是不准确的,主要包括以下有有一种场景。在MongoDB4.0过后的版本,即使不带谓词条件,在以下有有一种场景下count值假如有一天准。

1 所处孤立文档

2 mongo分片集群内部管理正在进行move chunk操作

本文主要针对你你是什么种生活场景,分析count不准的意味和规避最好的最好的土办法

而MongoDB3.6官方文档却是如此描述的

On a sharded cluster, db.collection.count() can result in an inaccurate count if orphaned documents exist or if a chunk migration is in progress.

To avoid these situations, on a sharded cluster, use the db.collection.aggregate() method

通过mongod日志其他 sh.isBalancerRunning()命令能必须确认,该表所处move chunk阶段;

为了方便观察,亲们将_waitForDelete设置为1,即迁移chunk完成后立即删除源端分片数据再进入下一次地chunk迁移,能必须观察到count结果值首先二个快速的增长过程,其他 是一个相对缓慢的减少过程;

每个chunk迁移循环上述过程,直到sh.isBalancerRunning()为OFF后,稳定在一个准确值。

从后边能必须看过,必须不带谓词条件的全表count才会所处结果不准的问提,其他 在你你是什么情形下,count结果值直接从表和chunk的元数据信息获取,在分布集群模式下假如有一天挨个去各个分片的chunk获取该表存取的count值,其他 做一个累加返回,其他 孤立文档的所处就造成返回结果大于准确结果。上个案例中一个产生了7090977个孤立文档。

什么时需模拟出孤立文档很简单,只时需在絮状movechunk期间强制杀掉主节点mongod守护程序运行运行即可,比如在已二个shard的情形下,上加另外一个shard到分片集群中,这时必然会涉及到絮状的movechunk操作,本文假如有一天采用你你是什么最好的最好的土办法。

mongodb在设计实现上,真正从源端向目标端copy数据的过程是串行的,也假如有一天必须逐个chunk迁移,其他 出于迁移速率单位上的考虑,最后一步的清理源端分片残留数据的操作是异步的,也假如有一天当修改完config元数据后,马能必须必须进入下一个chunk的迁移,并非时需守候源端分片清理完成。

清理源端分片旧chunk数据的操作装进一个队列中,在其他场景下它其他 其他 清理缓慢造成堆积,其他 这时primary节点crash,就会产生孤立文档。

从原本方面考虑,假如有一天产生了孤立文档,mongodb提供了清理分片上所有孤立文档的最好的最好的土办法,在每一个sharding节点上执行,最好的最好的土办法如下

其他 是MongoDB4.0过后的版本,count操作即使带了谓词条件结果值也会不准。这是其他 在4.0版本过后带谓词条件的count操作原理和普通的query不同,它并非会去检查遍历到的chunk我我觉得只属于一个shard,而4.0过后的版本,其原理就和普通query一样了,杜绝了结果值不准的情形。

从chunk迁移过程能必须看出,假如有一天迁移过程失败,亲们尚不得知它不是会清理目标端数据,理论上也会造成目标分片上的孤立文档,不过其他 movechunk串行处里,即使有,最多也就一个chunk块有问提;但其他 最后一步的清理源端旧chunk数据失败,则必然会在源端造成孤立文档,其他 最差的情形下其他 会产生絮状chunk的孤立文档。

从一方面说,减少孤立文档产生的数量,默认情形下,清理源端分片数据是异步调用的,但要能必须通过命令设置成同步调用,也假如有一天设置过后假如有一天primary节点crash,最多必须一个chunk其他 产生孤立,但并非推荐,意义假如有一天大。设置最好的最好的土办法为

在move chunk过程中,其他 是非count操作,普通的query肯定无法容忍你你是什么错误的,其他 根据过后的迁移过程分析,在movechunk的copy data期间,源端接收所有的访问请求;在修改元数据后,delete源端数据期间,目标端接受所有的访问请求。也假如有一天说,普通的query会去判断查询时需的chunk我我觉得属于且只属于一个shard,全版遵循config server中的元数据,什么都它的查询结果是准确的。

一般来说,movechunk操作为宜有以下步骤

从设计哲学上分析,既然4.0版本也如此保证不带谓词条件的count准确性,能必须认为是有有一种性能与速率单位上的折衷,其他 在你你是什么count场景下,大偏离 业务并非时需非常精准的count结果,而更强调"fast count"理念,即不让遍历数据,直接从元数据层面返回结果值;当然你时需准确的count值,也全版能必须用aggregate最好的最好的土办法代替,什么都必须认为这是一个bug,其他 说有待优化的点,其他 假如有一天有有一种count最好的最好的土办法在命令展示上过高 兼容,容易引起误解。

1 共同追求速率单位和准确性,能必须设置负载均衡窗口,在窗口以外禁止move chunk

2 强调数据准确性的场景,使用db.collection.aggregate()最好的最好的土办法代替count

3 针对带谓词条件的count操作,将mongo版本升级到4.0以上

4 针对跳出 絮状孤立文档的情形,做孤立文档清理

一般来说,除了其他 secondary延迟其他 造成查询secondary节点数据不准以外,关于count的准确性问提,在MongoDB4.0官方文档中含如此句子

On a sharded cluster, db.collection.count() without a query predicate can result in an inaccurate count iforphaned documents exist or if a chunk migration is in progress.

To avoid these situations, on a sharded cluster, use the db.collection.aggregate() method

孤立文档是其他 move chunk期间守护程序运行运行异常关闭造成的迁移失败或清理迁移后的源端chunk失败造成的,使得这偏离 记录在源端和目标端都所处,而在mongo分片集群的定义中,一个文档时需且必须属于一个chunk和shard。

显而易见,孤立文档其他 意味count不准,其他 孤立文档量如此来越多,时需造成占用额外的磁盘存储资源。