数据迁移:
根据用户ID来迁移数据,分页查询,根据创建时间排序。
发现10W+的数据同步之后只有7.2w多条,并且几乎每一个10w左右的数据量的用户都存在这样的问题,查找日志发现mongoDB有错误如下:
Caused by: com.mongodb.MongoQueryException: Query failed with error code 96 and error message 'Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.' on server XX.XX.XXX.XX:xxxx
at com.mongodb.operation.FindOperation$1.call(FindOperation.java:706)
at com.mongodb.operation.FindOperation$1.call(FindOperation.java:695)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:462)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:406)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:695)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:83)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:179)
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:132)
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:86)
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2667)
... 12 common frames omitte
造成原因很直接:
Sort operation used more than the maximum 33554432 bytes of RAM
直接翻译就是排序操作所使用的内存超过了33554432 字节(32M)。
也就是排序的时候加载到内存的数据太多了,这就解释了为什么基本上都是在7W多条数据的时候就出现了异常,因为恰好那么多数据就占了这么多内存。
解决方案在后面直接给了出来:
Add an index, or specify a smaller limit
-
增加索引:
为什么使用内存排序,是因为缺少索引,需要查询出来之后再在内存进行排序。
官方解释In MongoDB, sort operations can obtain the sort order by retrieving documents based on the ordering in an index. If the query planner cannot obtain the sort order from an index, it will sort the results in memory. Sort operations that use an index often have better performance than those that do not use an index. In addition, sort operations that do not use an index will abort when they use 32 megabytes of memory.
假如有索引则会使用索引排序
-
选择一个更小的限制,也就是不要查询那么多数据,换而言之。就是缩小需要排序的数据的范围,比如增加区分度更好的查询条件等
-
当然还有个比较狂野的方式就是我不改逻辑,反过来改mongoDB,那就是扩大排序使用的内存,不过这方式官方并没有写在错误信息中,一定程度表明了官方不推荐使用,并且这个修改治标不治本,数据量继续增大,还是会继续异常。
总结:排序还是推荐在排序字段上加合理的索引,特别是数量有一定规模的情况下(当然数量太大除非有底层分片,否则不推荐随意加索引),既减少排序成本也增加查询效率。

在进行数据迁移时遇到MongoDB排序查询异常,由于内存限制(32MB)导致排序操作失败。问题在于缺少相应字段的索引,使得数据在内存中排序。解决方案包括为排序字段添加索引,限制查询数据量,或者增加MongoDB的内存限制,但后两者非长久之计。建议在大规模数据下,特别是在排序操作中,合理添加索引以提高查询效率。
1851

被折叠的 条评论
为什么被折叠?



