Mongo优化笔记

最近MongoDb服务器负载比较高,容易出问题,这里把优化的方式整理一下。

1、由于各个项目组共用一个mongo实例,所以一个项目组的问题会影响到别的项目组,所以需要把各个项目的数据从一个实例中剥离出来。

2、根据请求接口的时间,数量,排查代码上的相关问题,重复查询、查询是否中索引、多次小量数据查询、mongo排序等。

3、优化索引,注意的是创建索引是一个比较重要的事情,如果数据量大,不想影响线上业务,要后台创建索引,在副本集上后台创建索引,primary是没问题的,secondary在同步索引的时候,会阻塞,如果读在secondary上的话,这点需要注意。

4、我们现在的Mongo用的副本集,之前配置成了读写分离,来解决primary的负载较高的问题,后来发现secondary的负载会升高,secondary有跟primary一样的写请求,并且有可能存在数据不同步的问题,副本集的意义在故障切换这块比较大,后期我们会把Mongo由副本集改为分片的部署方式。

索引优化排查:

1、利用explain来查看一个查询的查询过程,

mgset-134234:SECONDARY> db.userInfo.find({phone_number:'11111'}).explain('executionStats')
{
    "queryPlanner" : {              
        "plannerVersion" : 1,
        "namespace" : "source.userInfo",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "phone_number" : {
                "$eq" : "11111"
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "phone_number" : 1
                },
                "indexName" : "phone_number_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "phone_number" : [ ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "phone_number" : [
                        "[\"11111\", \"11111\"]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 0,
        "executionTimeMillis" : 0,
        "totalKeysExamined" : 0,
        "totalDocsExamined" : 0,
        "executionStages" : {
            "stage" : "FETCH",
            "nReturned" : 0,
            "executionTimeMillisEstimate" : 0,
            "works" : 1,
            "advanced" : 0,
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 0,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 0,
                "executionTimeMillisEstimate" : 0,
                "works" : 1,
                "advanced" : 0,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "phone_number" : 1
                },
                "indexName" : "phone_number_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "phone_number" : [ ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "phone_number" : [
                        "[\"11111\", \"11111\"]"
                    ]
                },
                "keysExamined" : 0,
                "seeks" : 1,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
    },
    "ok" : 1
}

查看executionStats字段会发现FETCH->IXSCAN,表明中索引。

stage各个值的含义:

  • COLLSCAN 全表扫描
  • IXSCAN 索引扫描
  • FETCH 根据索引去检索指定document
  • SHARD_MERGE  将各个分片返回数据进行merge
  • SORT    表明在内存中进行了排序

只是列了几个比较常见的,详细的请参考MongoDB中文社区的干货系列

慢查询日志排查

有一个操作是创建了一个三键索引,删除了两键索引,但是在慢查询日志查看过程中,发现这个查询所中的还是两键索引,在Mongo Shell中,explain查看,中的是三键索引,通过查阅相关资料,Mongo的cache plan影响的

PlanCache help
    db.userInfo.getPlanCache().help() - show PlanCache help
    db.userInfo.getPlanCache().listQueryShapes() - displays all query shapes in a collection
    db.userInfo.getPlanCache().clear() - drops all cached queries in a collection
    db.userInfo.getPlanCache().clearPlansByQuery(query[, projection, sort, collation]) - drops query shape from plan cache
    db.userInfo.getPlanCache().getPlansByQuery(query[, projection, sort, collation]) - displays the cached plans for a query shape

通过相关命令,删除cache plan,mongo会自动生成新的cache plan

posted @ 2018-05-12 11:11  子凡灬  阅读(249)  评论(0编辑  收藏  举报