• MongoDB CPU使用较高,如何排查?


    前言

    首先,我们简单梳理一下,CPU 在什么情况下才算负载较高?负载查看是通过"uptime"命令查看。大家都知道,命令显示的结果分别表示1分钟、5分钟、15分钟的负载情况,这点就不多做说明。在系统负荷方面,多核CPU与多CPU效果类似,所以考虑系统负荷的时候,必须考虑这台电脑有几个CPU、每个CPU有几个核心。然后,把系统负荷除以总的核心数,只要每个核心的负荷不超过1.0,就表明电脑正常运行。从单棵CPU来说,一般负载不超过0.7都无需关系,当超过该值得时候,就应该开始调查了,问题出在哪里,防止情况恶化。

    负载计算公式:

    [root@mongodb-1219 ~]# grep 'model name' /proc/cpuinfo | wc -l
    24
    [root@mongodb-1219 ~]# echo "0.7 * 24" |bc
    16.8

    N个CPU的电脑,可接受的系统负荷最大为n。正常情况为"N * 0.7",该值为可观状态。

    案例

    [root@mongodb-1219 ~]# top
    top - 09:58:34 up 325 days, 14:15,  5 users,  load average: 84.13, 156.16, 108.10
    Tasks: 1078 total,   1 running, 1077 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  2.9 us,  0.2 sy,  0.0 ni, 96.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem : 32639968 total,  1817952 free,   998372 used, 29823644 buff/cache
    KiB Swap: 16777212 total, 16773128 free,     4084 used. 29489896 avail Mem 
    
       PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                  
    333052 root      20   0 34.607g 657716 262228 S  74.3  2.0 209:12.13 mongod                                                   
    366752 root      20   0  147216   3128   1432 S   1.0  0.0   0:02.50 top                                                      
    367511 root      20   0  147072   3024   1416 R   1.0  0.0   0:00.19 top                                                      
      2189 root      20   0  686788  36396   4188 S   0.3  0.1 267:57.64 salt-minion                                              
         1 root      20   0   69856  31864   1964 S   0.0  0.1  15:13.08 systemd

    如图所示,该服务器CPU使用高达74%(截图存在一定的偏差,其实此时的用户占用CPU值相当高)。根据信息可以得知,是用户态CPU使用较高,那么这种情况一般都是用户使用不合理。这种情况,不仅在MongoDB中,MySQL中也会有类似的问题。

    Setup 1.查看相关日志

    查看日志,发现有条查询语句竟然耗时7077ms,看样子有问题。(此时估摸着,就是开发没有加索引。)

    Setup 2.分析数据库正在执行的请求

    用户可以通过 Mongo Shell 连接,并执行 db.currentOp() 命令,能看到数据库当前正在执行的操作,如下是该命令的一个输出示例,标识一个正在执行的操作。重点关注几个字段:

      client:请求是由哪个客户端发起的;

      opid:操作的opid,有需要的话,可以通过 db.killOp(opid) 直接干掉的操作;
      secs_running/microsecs_running: 这个值重点关注,代表请求运行的时间,如果这个值特别大,就得注意了,看看请求是否合理;
      query/ns: 这个能看出是对哪个集合正在执行什么操作;
      lock*:还有一些跟锁相关的参数,需要了解可以看官网文档,本文不做详细介绍;

    Setup 3.分析数据库的慢请求

    MongoDB 支持 profiling 功能,将请求的执行情况记录到同DB下的 system.profile 集合里,profiling 有3种模式:
      关闭 profiling
      针对所有请求开启 profiling,将所有请求的执行都记录到 system.profile 集合
      针对慢请求 profiling,将超过一定阈值的请求,记录到system.profile 集合
      默认请求下,MongoDB 的 profiling 功能是关闭,生产环境建议开启,慢请求阈值可根据需要定制,如不确定,直接使用默认值100ms。

     关于profiling功能说明,参考文档。默认请求下,MongoDB 的 profiling 功能是关闭,生产环境建议开启,慢请求阈值可根据需要定制,如不确定,直接使用默认值100ms。

    operationProfiling:
      mode: slowOp
      slowOpThresholdMs: 100
    

    基于上述配置,MongoDB 会将超过 100ms 的请求记录到对应DB 的 system.profile 集合里,system.profile 默认是一个最多占用 1MB 空间的 capped collection。

    查看最近3条 慢请求,{$natrual: -1} 代表按插入数序逆序
    db.system.profile.find().sort({$natrual: -1}).limit(3)

    情况1:全盘扫描

           全集合(表)扫描 COLLSCAN,当一个查询(或更新、删除)请求需要全表扫描时,是非常耗CPU资源的,所以当你在 system.profile 集合 或者日志文件发现 COLLSCAN 关键字时,就得注意了,很可能就是这些查询吃掉了你的 CPU 资源;确认一下,如果这种请求比较频繁,最好是针对查询的字段建立索引来优化。

            一个查询扫描了多少文档,可查看 system.profile 里的 docsExamined 的值,该值越大,请求CPU开销越大。关键字:COLLSCAN、 docsExamined。

    情况2:索引未添加或不合理

           一个走索引的查询,扫描了多少条索引,可查看 system.profile 里的 keysExamined 字段,该值越大,CPU 开销越大。关键字:IXSCAN、keysExamined。

    情况3:大量数据排序

           当查询请求里包含排序的时候,如果排序无法通过索引满足,MongoDB 会在内存里将结果进行排序,而排序这个动作本身是非常耗 CPU 资源的,优化的方法仍然是建立索引,对经常需要排序的字段,建立索引。当你在 system.profile 集合 或者 日志文件发现 SORT 关键字时,就可以考虑通过索引来优化排序。当请求包含排序阶段时, system.profile 里的 hasSortStage 字段会为 true。关键字:SORT、hasSortStage。

           其他还有诸如建索引,aggregationv等操作也可能非常耗 CPU 资源,但本质上也是上述几种场景;建索引需要全表扫描,而vaggeregation 也是遍历、查询、更新、排序等动作的组合。

          基本上就是以上几种情况,还有的话就是MongoDB确实已经达到瓶颈,此时可能需要通过shard来解决。

  • 相关阅读:
    图解持续集成纯命令行实现.Net项目每日构建(流程支持)
    (转) 持续集成(第一版)Martin Fowler等著
    Glut框架示例
    常见希腊字母读法
    【译】VC10中的C++0x特性 Part 2 (2):右值引用
    【排序】排序算法之交换排序
    OpenGL开发环境配置
    Android 上实现水波特效
    有关singleton的资料
    【排序】排序算法之选择排序
  • 原文地址:https://www.cnblogs.com/yangxiaoyi/p/7504753.html
Copyright © 2020-2023  润新知