mtools-你可能没用过的mongodb神器
转载:mongodb可以通过profile来监控数据 (mongodb性能优化)
其他一些mtools用法: 使用Mtools分析MongoDB日志文件

在MySQL中,通过慢查询日志作为性能优化的主要切入点,SQL优化步骤+慢SQL分析
Mongo中也有类似的功能

开启慢日志

开启Profiling功能

mongodb可以通过profile来监控数据,进行优化。
getProfilingLevel()
通过命令db.getProfilingLevel()查看profiling开启状态:

  • 0代表关闭
  • 1代表记录慢命令,
  • 2代表全部

setProfilingLevel(level)
通过db.setProfilingLevel(level)设置profiling等级,level等级值同上。
level为1的时候,慢命令默认值为100ms,可以通过如db.setProfilingLevel(1,50),慢日志就设置为50ms

配置文件开启
可以通过配置文件,配置profilling

systemLog:
    destination: file
    path: "/data/mongodb/logs/mongod.log" #慢日志存放目录
logAppend: true 

operationProfiling:
   slowOpThresholdMs: 100  # 100ms
   mode: slowOp

启动命令配置
mongod --profile=1 --slowms=200

查看慢日志-集合

通过db.system.profile.find()查看当前的监控日志。

> db.system.profile.find({millis:{$gt:500}})
{"ts":ISODate("2011-07-23T02:50:13.941Z"),"info":"query order.order reslen:11022 nscanned:672230  \nquery: { status: 1.0 } nreturned:101 bytes:11006 640ms","millis":640}
{"ts":ISODate("2011-07-23T02:51:00.096Z"),"info":"query order.order reslen:11146 nscanned:672302  \nquery: { status: 1.0, user.uid: { $gt: 1663199.0 } }  nreturned:101 bytes:11130 647ms","millis":647}

这里值的含义是:

  • ts:命令执行时间
  • info:命令的内容
  • query:代表查询
  • order.order: 代表查询的库与集合(命名空间)
  • reslen:返回的结果集大小,byte数
  • nscanned:扫描记录数量
  • nquery:后面是查询条件
  • nreturned:返回记录数及用时
  • millis:所花时间

如果发现:时间比较长,那么就需要作优化。

  • nscanned数很大,或者接近记录总数,那么可能没有用到索引查询
  • reslen很大,有可能返回没必要的字段
  • nreturned很大,那么有可能查询的时候没有加限制,加分页限制

日常使用的慢日志(system.profile)查询命令

# 删除慢日志集合
db.system.profile.drop()

5 日常使用的慢日志(system.profile)查询

#返回最近的10条记录
db.system.profile.find().limit(10).sort({ ts : -1 }).pretty()

#返回所有的操作,除command类型的
db.system.profile.find( { op: { $ne : ‘command‘ } }).pretty()

#返回特定集合
db.system.profile.find( { ns : ‘mydb.test‘ } ).pretty()

#返回大于5毫秒慢的操作
db.system.profile.find({ millis : { $gt : 5 } } ).pretty()

mtools分析

mtools是什么

mtools 是由MongoDB 官方工程师实现的一套工具集,可以很快速的日志文件查询分析、统计功能,此外还支持本地集群部署管理,非常便于新手学习。
mtools使用python编写完成,可通过pipy网站 获取;
该工具包含了以下几个关键组件:

  • mlaunch:支持快速搭建本地测试环境,可以是单机、副本集、分片集群。
  • mlogfilter:日志过滤组件,支持按时间检索慢查询、全表扫描操作,支持通过多个属性进行信息过滤,支持输出为JSON格式。
  • mplotqueries:支持将日志分析结果转换为图表形式,依赖于tkinter(python图形模块)、和matplotlib模块。
  • mlogvis:支持将日志分析结果转换为一个独立的HTML页面,实现与mplotqueries同样的功能。

1.简易集群管理(略)

执行以下命令,可以启动一个单节点的mongod进程。

# mlaunch init --single
launching: "mongod" on port 27017

2. 日志统计

总体信息
mloginfo 是一个用于做日志信息统计的工具,输入以下命令:

# mloginfo mongo.log
     source: mongo.log
       host: MongoDB_1:10001
        start: 2018 May 18 16:33:11.692
        end: 2018 May 19 01:13:08.290
date format: iso8601-local
     length: 144480
     binary: mongod
    version: 3.4.10
    storage: wiredTiger

可以看到日志的起止时间范围、主机端口、版本、数据库引擎等概要信息。

连接数
当我们希望检查客户端的连接数情况时,可以执行以下命令:

# mloginfo mongo.log --connections
CONNECTIONS
     total opened: 14282
     total closed: 14358
    no unique IPs: 4
socket exceptions: 0
127.0.0.1 opened: 12886 closed: 12889
172.21.0.29 opened: 658 closed: 716
172.21.0.28 opened: 461 closed: 490
172.21.0.27 opened: 277 closed: 263

通过这样的信息,进一步判断是否存在连接过载等异常情况。

事件统计
又或者,你希望统计出当前某些事件的发生频次。

# mloginfo mongo.log --distinct
DISTINCT
   14358 end connection ... ( ... now open)
   14281 connection accepted from ... # ... ( ... now open)
   13075 received client metadata from ... :
    5340 Successfully authenticated as principal ... on
    1194 Use of the aggregate command without the 'cursor'
     338 build index on: ... properties:
     244 building index using bulk method; build may temporarily use up to ... megabytes of RAM
     234 ns: ... key: ... name:
     219 Refreshing chunks for collection ... based on version
     218 Refresh for collection ... took ... ms and found version
     179 Index ... :

慢查询
在业务问题分析中,慢查询是最常见的问题。

# mloginfo mongo.log --queries --sort count
QUERIES
namespace                  operation      pattern                              count      min (ms)    max (ms)  mean (ms)    95%-ile (ms) sum (ms)
nsspace.StatisticsHour   find             {"$and": [{"recordTime": 1}]..}     22331      276       747          345          414.0            7720736
nsspace.StatisticsHour   getmore       {"aggregate": 1, "cursor": ...}]}    231          200      304          227          272.0             52587
dmspace.DeviceInfo      remove          {"_id": 1}                              109        205      1786          420          771.0            45860
cmspace.DeviceData     update          {"appId": 1, "deviceId": 1}          95          201      1802          431          824.5            40966
dmspace.TaskHistory    update          {"_id": 1}                                54          268      2643          692          2019.0          37413
nsspace.StatisticsDay     find              {"$and": [{"recordTime": 1}], ..}   31          201      348            241          345.0            7472

如上面的命令,将显示所有慢查询,并按出现次数排序

重启信息

# mloginfo mongo.log --restart
RESTARTS
   May 18 21:37:51 version 3.4.10
   May 18 21:48:33 version 3.4.10

通过检测重启信息,对系统潜在的故障进行评估分析。

副本集切换
同样,主备切换可能导致一定的业务失败,需要定期监测。

# mloginfo mongo.log --rsstate
RSSTATE
date host state/message
()
May 18 21:48:53 172.21.0.29:10001 ARBITER
May 18 21:49:26 172.21.0.28:10001 SECONDARY

3. 日志过滤

mlogfilter是一个强大的日志过滤模块,相比linux 的grep/egrep的文本过滤,该组件可以对日志内容进行解析,并按我们想要的结果进行过滤。

查看超过10s的慢操作

# mlogfilter mongo.log --slow 10000 --shorten 200

查看慢扫描操作
慢扫描是指该操作需要扫描过多的记录(超过1w行),且返回数量不足扫描数量的1/100,这样的操作通常对CPU消耗很高,也比较低效,

# mlogfilter mongo.log --scan --shorten 200

根据名称空间过滤

# mlogfilter mongo.log --namespace dmspace.DeviceInfo

根据操作类型过滤

# mlogfilter mongo.log --namespace dmspace.DeviceInfo

根据操作类型过滤

# mlogfilter mongo.log --operation update

获取某时间点之后1小时的日志

# mlogfilter mongo.log --from Apr 6 0:00 --to "+1h" | tail -n3

mlogfilter提供了非常灵活的日期条件设置,除了可以指定起始、结束时间之外,还能通过偏移量划分范围。

时区转换

# mlogfilter mongo.log --tiemzone 2 > mongo-correct.log

以上命令将日期调大2个时区,输出到mongo-correct.log,这在处理国际化系统的场景中非常有用。

4. 图表呈现

mplotqueries 是基于tkinter实现的图表组件,可以将日志中扁平的文字信息转换为图表形式。

操作时长-散列图
输入以下命令:

mplotqueries mongo.log --group operations --output-file operations.png

你可以得到一个按操作分组输出的散点图,如下图:
在这里插入图片描述
左侧的Y轴是duration,即操作的执行时长,下边的X轴是时间。每个操作在图中都会有一个描点,因此散点图会存在许多重叠。

按名称空间进行分组(限显示20个)-扫描记录数量
当然,你也可以通过集合名称进行分组输出,如下面的命令:

mplotqueries mongo.log --group namespace --group-limit 20 --type scatter --yaxis nscanned --output-file namespace_nscan.png

输出的图表将按名称空间进行分组(限显示20个),y轴为nscanned值,即扫描记录数量
在这里插入图片描述
默认情况下,y轴的呈现为时长(during),可指定为其他指标:

指标名称说明
nscanned扫描数
nupdated更新数
ninserted插入数
ntoreturn返回数
numYields让步次数
r读锁
w写锁

某个时间段,某类操作或某个集合的操作占比
有时候你并不关系具体的某个操作,而是希望看到某个时间段,某类操作或某个集合的操作占比
比如每小时,每个集合的操作比例分布,此时可以采用直方图

mplotqueries mongo.log --group namespace --bucketsize 3600 --group-limit 10 --type histogram --output-file namespaces_perhour.png

在这里插入图片描述

连接变更统计
在前面已经讲过,连接数的监测工作非常重要,mplotqueries也提供了连接变更统计类型

mplotqueries mongo.log --type connchurn --bucketsize 3600 --output-file connchurn_perhour.png

在这里插入图片描述
扫描数/返回数
在大部分情况下,低效的操作往往来自大量的scan扫描,尤其当return数远小于scan时会更加低效。
可以通过指定 nscanned/n参数输出该维度的图表,即扫描数/返回数

mplotqueries mongo.log --type nscanned/n --group-limit 20 --output-file nscan.png

在这里插入图片描述

输出事件持续图
往往在跟踪某一类耗时操作或事件时需要用到,比如oplog的同步、创建索引等,我们希望看到事件的执行时段。
同时还需要伴随一些操作统计,用于配合做资源监控分析。具体一点就是,你执行了一个耗时操作,在某些情况下对业务访问可能
产生了影响,如业务访问超时并伴随DB服务器资源的告警,如CPU飙高,在后续的分析中希望通过耗时操作、以及同时段业务访问的分布进行综合分析。

以下的命令展示了一个典型用法

# 创建一个overlay
grep "index" mongo.log | mplotqueries --type durline --overlay
# 叠加overlay输出图表
mplotqueries mongo.log --group operation --output-file duration.png

在这里插入图片描述

mlogvis

如果不希望生成那么多的图表,mtools还提供了一个偷懒的工具 mlogvis。可以直接生成html页面,内置强大的脚本.基本上覆盖了mplotqueries的绝大多数图表功能。

# mlogvis mongo.log

在这里插入图片描述

生成的html出错,需要将head中 d3.js替换为<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

安装mtools

安装python

wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz

$ cd Python-3.6.8/
$ ./configure --with-ssl # 带上ssl不然pip会出现错误
$ make
$ make install

安装pip3

yum install python-tools

pip3 install psutil
pip3 install pymongo
pip3 install matplotlib
pip3 install numpy

安装mtools

pip3 install mtools
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐