• Mongo排序超32M问题解决 仅此而已


    背景

    事件列表分页查询时,报如下错:

    说明:事件表中,如果事件如果聚合了很多告警,那这些事件的大小就会很大

    问题分析

    问题说明

    MongoDB的 sort 操作是把数据拿到内存中再进行排序的,为了节约内存,默认给 sort 操作限制了最大内存为32M(mongo4.3以上版本是100M),当数据量超过限制后,就会抛异常。

    如果排序或者查询时,命中了排序字段,那排序的时候,只需要将排序字段拉到内存中进行排序,如果未命中索引,则会将查询出来的所有文档拉到内存中进行排序。

    代码分析

    先来看下报错那一行的代码:

    这里的排序,使用的是 lastDetectionTime 字段,来看下事件表建立的索引有哪些:

    通过代码可以看到,查询条件只有主键ID列表,所以排序的时候,是不会走任何索引的。

     

    解决方案

    方案一:修改排序限制(不推荐)

    将mongo排序限制改为100M。执行如下命令:

    /usr/local/qingteng/mongodb/bin/mongo --host localhost --port 27017 -u qingteng -p fMElKUz36MY00ceg --authenticationDatabase admin
    use amdin;
    db.runCommand({
        setParameter: 1,
        "internalQueryExecMaxBlockingSortBytes": 104857600
    });

    执行效果:

    方案二:排序字段创建索引(不推荐)

    由于现在的查询条件不会命中组合索引 comId_lastDetectionTime,那只需要改下这个索引就可以命中。

    删除组合索引comId_lastDetectionTime,新建组合索引lastDetectionTime_comId,命令:

    db.ids_incident.createIndex({lastDetectionTime:-1, comId:1},{name:"lastDetectionTime_comId"})

    方案三:修改查询条件

    既然现有的查询条件不会命中组合索引 comId_lastDetectionTime,那就改下查询条件,让查询字段带上该组合索引。修改后的代码如下:

    说明:最上面的IncidentQuery中是一定会包含comId、startTime、endTime的

  • 相关阅读:
    java高级语法4:集合
    java高级语法3:异常和注解
    Java高级语法2:Lambda表达式
    VS编译时卡在正在从以下位置加载xxx.dll符号
    mysql中的外键
    localhost和127.0.0.1的区别
    添加依赖项
    代码版本控制——TFS
    优化版冒泡排序
    visual studio vode 汉化
  • 原文地址:https://www.cnblogs.com/xuwenjin/p/16393900.html
Copyright © 2020-2023  润新知