MongoDB调优

三大导致 MongoDB 性能不佳的原因

1)慢查询
2)阻塞等待
3)硬件资源不足
1,2通常是因为模型/索引设计不佳导致的。
排查思路:按1-2-3依次排查。

影响 MongoDB 性能的因素

555.png

MongoDB 性能监控工具

Free Monitoring

从版本 4.0 开始,MongoDB 为独立实例和复制集提供免费的云监控。免费监控提供有关部署的信息,包括:

  • 操作执行次数
  • 内存使用情况
  • CPU使用率
  • 操作数
# 启用监控
db.enableFreeMonitoring()
# 禁止监控
db.disableFreeMonitoring()
# 获取监控信息
db.getFreeMonitoringStatus()

mongostat

mongostat 是 MongoDB 自带的监控工具,其可以提供数据库节点或者整个集群当前的状态视图。该功能的设计非常类似于 Linux 系统中的 vmstat 命令,可以呈现出实时的状态变化。不同的是,mongostat 所监视的对象是数据库进程。mongostat 常用于查看当前的 QPS/内存使用/连接数,以及多个分片的压力分布。mongostat 采用 Go 语言实现,其内部使用了db.serverStatus()命令,要求执行用户需具备 clusterMonitor 角色权限。

mongostat -h 192.168.65.174 --port 28017 -ufirechou -pfirechou --authenticationDatabase=admin --discover -n 300 2

参数说明:

-h:指定监听的主机,分片集群模式下指定到一个 mongos 实例,也可以指定单个 mongod,或者复制集的多个节点。
–port:接入的端口,如果不提供则默认为 27017。
-u:接入用户名,等同于-user。
-p:接入密码,等同于-password。
–authenticationDatabase:鉴权数据库。
–discover:启用自动发现,可展示集群中所有分片节点的状态。
-n 300 2:表示输出300次,每次间隔2s。也可以不指定“-n 300”,此时会一直保持输出。

指标说明:

指标名说明
inserts每秒插入数
query每秒查询数
update每秒更新数
delete每秒删除数
getmore每秒 getmore 数
command每秒命令数,涵盖了内部的一些操作
%dirtyWiredTiger 缓存中脏数据百分比
%usedWiredTiger 正在使用的缓存百分比
flushesWiredTiger 执行 CheckPoint 的次数
vsize虚拟内存使用量
res物理内存使用量
qrw客户端读写等待队列数量,高并发时,一般队列值会升高
arw客户端读写活跃个数
netIn网络接收数据量
netOut网络发送数据量
conn当前连接数
set所属复制集名称
repl复制节点状态(主节点/二级节点……)
time时间戳

mongostat 需要关注的指标主要有如下几个:

  • 插入、删除、修改、查询的速率是否产生较大波动,是否超出预期。
  • qrw、arw:队列是否较高,若长时间大于 0 则说明此时读写速度较慢。
  • conn:连接数是否太多。
  • dirty:百分比是否较高,若持续高于 10% 则说明磁盘 I/O 存在瓶颈。
  • netIn、netOut:是否超过网络带宽阈值。
  • repl:状态是否异常,如 PRI、SEC、RTR 为正常,若出现 REC 等异常值则需要修复。

使用交互模式:
mongostat 一般采用滚动式输出,即每一个间隔后的状态数据会被追加到控制台中。从 MongoDB 3.4 开始增加了--interactive选项,用来实现非滚动式的监视,非常方便。

mongostat -h 192.168.65.174 --port 28017 -ufirechou -pfirechou --authenticationDatabase=admin --discover --interactive -n 2

mongotop

mongotop 命令可用于查看数据库的热点表,通过观察 mongotop 的输出,可以判定是哪些集合占用了大部分读写时间。mongotop 与 mongostat 的实现原理类似,同样需要 clusterMonitor 角色权限。

mongotop -h 192.168.65.174 --port=28017 -ufirechou -pfirechou --authenticationDatabase=admin

默认情况下,mongotop 会持续地每秒输出当前的热点表。
指标说明:

指标名说明
ns集合名称空间
total花费在该集合上的时长
read花费在该集合上的读操作时长
write花费在该集合上的写操作时长

mongotop 通常需要关注的因素主要包括:

  • 热点表操作耗费时长是否过高。这里的时长是在一定的时间间隔内的统计值,它代表某个集合读写操作所耗费的时间总量。在业务高峰期时,核心表的读写操作一般比平时高一些,通过 mongotop 的输出可以对业务尖峰做出一些判断。
  • 是否存在非预期的热点表。一些慢操作导致的性能问题可以从 mongotop 的结果中体现出来。

mongotop 的统计周期、输出总量都是可以设定的。

# 最多输出100次,每次间隔时间为2s
mongotop -h 192.168.65.174 --port=28017 -ufirechou -pfirechou --authenticationDatabase=admin -n 100 2

Profiler 模块

Profiler 模块可以用来记录、分析 MongoDB 的详细操作日志。默认情况下该功能是关闭的,对某个业务库开启 Profiler 模块之后,符合条件的慢操作日志会被写入该库的system.profile集合中。Profiler 的设计很像代码的日志功能,其提供了几种调试级别:

级别说明
0日志关闭,无任何输出
1部分开启,仅符合条件(时长大于slowms)的操作日志会被记录
2日志全开,所有的操作日志都被记录

对当前的数据库开启 Profiler 模块:

# 将level设置为2,此时所有的操作会被记录下来。
db.setProfilingLevel(2)
# 检查是否生效
db.getProfilingStatus()
  • slowms 是慢操作的阈值,单位是毫秒;
  • sampleRate 表示日志随机采样的比例,1.0 则表示满足条件的全部输出;

如果希望只记录时长超过 500ms 的操作,则可以将 level 设置为 1:

db.setProfilingLevel(1,500)

还可以进一步设置随机采样的比例:

db.setProfilingLevel(1,{slowms:500,sampleRate:0.5})

查看操作日志
开启 Profiler 模块之后,可以通过system.profile集合查看最近发生的操作日志

db.system.profile.find().limit(5).sort({ts:-1}).pretty()

这里需要关注的一些字段主要如下所示:

  • op:操作类型,描述增加、删除、修改、查询。
  • ns:名称空间,格式为{db}.{collection}
  • Command:原始的命令文档。
  • Cursorid:游标 ID。
  • numYield:操作数,大于 0 表示等待锁或者是磁盘 I/O 操作。
  • nreturned:返回条目数。
  • keysExamined:扫描索引条目数,如果比 nreturned 大出很多,则说明查询效率不高。docsExamined:扫描文档条目数,如果比 nreturned 大出很多,则说明查询效率不高。
  • locks:锁占用的情况。
  • storage:存储引擎层的执行信息。
  • responseLength:响应数据大小(字节数),一次性查询太多的数据会影响性能,可以使用 limit、batchSize 进行一些限制。
  • millis:命令执行的时长,单位是毫秒。
  • planSummary:查询计划的概要,如 IXSCAN 表示使用了索引扫描。
  • execStats:执行过程统计信息。
  • ts:命令执行的时间点。

根据这些字段,可以执行一些不同维度的查询。比如查看执行时长最大的 10 条操作记录查看某个集合中的 update 操作日志

db.system.profile.find().limit(10).sort({millis:-1}).pretty()

查看某个集合中的 update 操作日志

db.system.profile.find({op:"update",ns:"shop.user"})

注意事项

  • system.profile是一个 1MB 的固定大小的集合,随着记录日志的增多,一些旧的记录会被滚动删除。
  • 在线上开启 Profiler 模块需要非常谨慎,这是因为其对 MongoDB 的性能影响比较大。建议按需部分开启,同时 slowms 的值不要设置太低。
  • sampleRate 的默认值是 1.0,该字段可以控制记录日志的命令数比例,但只有在 MongoDB 4.0 版本之后才支持。
  • Profiler 模块的设置是内存级的,重启服务器后会自动恢复默认状态。

db.currentOp()

Profiler 模块所记录的日志都是已经发生的事情,db.currentOp()命令则与此相反,它可以用来查看数据库当前正在执行的一些操作。想象一下,当数据库系统的 CPU 发生骤增时,我们最想做的无非是快速找到问题的根源,这时db.currentOp就派上用场了。
db.currentOp()读取的是当前数据库的命令快照,该命令可以返回许多有用的信息,比如:

  • 操作的运行时长,快速发现耗时漫长的低效扫描操作。
  • 执行计划信息,用于判断是否命中了索引,或者存在锁冲突的情况。
  • 操作 ID、时间、客户端等信息,方便定位出产生慢操作的源头。

对示例操作的解读如下:
(1)从 ns、op 字段获知,当前进行的操作正在对test.items集合执行 update 命令。
(2)command 字段显示了其原始信息。其中,command.qcommand.u分别展示了 update 的查询条件和更新操作。
(3)"planSummary":"COLLSCAN" 说明情况并不乐观,update 没有利用索引而是正在全表扫描。
(4)microsecs_running:NumberLong(186070)表示操作运行了 186ms,注意这里的单位是微秒。

优化方向:

  • value 字段加上索引;
  • 如果更新的数据集非常大,要避免大范围 update 操作,切分成小批量的操作;

opid 表示当前操作在数据库进程中的唯一编号。如果已经发现该操作正在导致数据库系统响应缓慢,则可以考虑将其“杀”死。

db.killOp(4001)

db.currentOp默认输出当前系统中全部活跃的操作,由于返回的结果较多,我们可以指定一些过滤条件:

  • 查看等待锁的增加、删除、修改、查询操作
db.currentOp({waitingForLock:true,$or:[{op:{$in:["insert","update","remove"]}},{"query.findandmodify":{$exists:true}}]
})
  • 查看执行时间超过 1s 的操作
db.currentOp({secs_running:{$gt:1}
})
  • 查看 test 数据库中的操作
db.currentOp({ns:/test/
})

currentOp命令输出说明:

currentOp.type:操作类型,可以是 op、idleSession、idleCursor 的一种,一般的操作信息以 op 表示。其为 MongoDB 4.2 版本新增功能。
currentOp.host:主机的名称。currentOp.desc:连接描述,包含 connectionId。
urrentOp.connectionId:客户端连接的标识符。
currentOp.client:客户端主机和端口。
currentOp.appName:应用名称,一般是描述客户端类型。
currentOp.clientMetadata:关于客户端的附加信息,可以包含驱动的版本。
currentOp.currentOpTime:操作的开始时间。MongoDB 3.6 版本新增功能。
currentOp.lsid:会话标识符。MongoDB 3.6 版本新增功能。
currentOp.opid:操作的标志编号。
currentOp.active:操作是否活跃。如果是空闲状态则为 false。
currentOp.secs_running:操作持续时间(以秒为单位)。
currentOp.microsecs_running:操作持续时间(以微秒为单位)。
currentOp.op:标识操作类型的字符串。可能的值是:“none” “update” “insert”“query”“command” “getmore” “remove” “killcursors”。其中,command操作包括大多数命令,如createIndexes和findAndModify。
currentOp.ns:操作目标的集合命名空间。
currentOp.command:操作的完整命令对象的文档。如果文档大小超过 1KB,则会使用一种 $truncate 形式表示。
currentOp.planSummary:查询计划的概要信息。
currentOp.locks:当前操作持有锁的类型和模式。
currentOp.waitingForLock:是否正在等待锁。
currentOp.numYields:当前操作执行 yield(让步)的次数。一些锁互斥或者磁盘 I/O 读取都会导致该值大于 0。
currentOp.lockStats:当前操作持有锁的统计。
currentOp.lockStats.acquireCount:操作以指定模式获取锁的次数。
currentOp.lockStats.acquireWaitCount:操作获取锁等待的次数,等待是因为锁处于冲突模式。acquireWaitCount 小于或等于 acquireCount。
currentOp.lockStats.timeAcquiringMicros:操作为了获取锁所花费的累积时间(以微秒为单位)。timeAcquiringMicros 除以 acquireWaitCount 可估算出平均锁等待时间。
currentOp.lockStats.deadlockCount:在等待锁获取时,操作遇到死锁的次数。

注意事项:

  • db.currentOp 返回的是数据库命令的瞬时状态,因此,如果数据库压力不大,则通常只会返回极少的结果。
  • 如果启用了复制集,那么 currentOp 还会返回一些复制的内部操作(针对local.oplog.rs),需要做一些筛选。
  • db.currentOp 的结果是一个 BSON 文档,如果大小超过 16MB,则会被压缩。可以使用聚合操作 $currentOp 获得完整的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/630250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis经典面试题

说说你对Redis的理解 Redis是一个基于Key-Value存储结构的开源内存数据库,也是一种NoSQL数据库。 它支持多种数据类型,包括String、Map、Set、ZSet和List,以满足不同应用场景的需求。 Redis以内存存储和优化的数据结构为基础,提…

Python爬虫实战:IP代理池助你突破限制,高效采集数据

当今互联网环境中,为了应对反爬虫、匿名访问或绕过某些地域限制等需求,IP代理池成为了一种常用的解决方案。IP代理池是一个包含多个可用代理IP地址的集合,可以通过该代理池随机选择可用IP地址来进行网络请求。 IP代理池是一组可用的代理IP地址…

网页设计(十一)JavaScript事件分析

一、设计校园办公系统认证页面 校园办公系统认证页面 校园办公系统认证页面初始布局 卡号有效性检查页面 口令有效性检查页面 二次口令有效性检查页面 QQ/微信有效性检查图 <!-- prj_11_1.html --> <!doctype html> <html lang"en"><…

Java设计模式-迭代器模式

迭代器模式 一、概述二、结构三、案例实现四、优缺点五、使用场景六、JDK源码解析 一、概述 定义&#xff1a; 提供一个对象来顺序访问聚合对象中的一系列数据&#xff0c;而不暴露聚合对象的内部表示。 二、结构 迭代器模式主要包含以下角色&#xff1a; 抽象聚合&#xf…

postman做接口测试

之前搞自动化接口测试&#xff0c;由于接口的特性&#xff0c;要验证接口返回xml中的数据&#xff0c;所以没找到合适的轮子&#xff0c;就自己用requests造了个轮子&#xff0c;用着也还行&#xff0c;不过就是case管理有些麻烦&#xff0c;近几天又回头看了看postman也可以玩…

论文笔记(四十)Goal-Auxiliary Actor-Critic for 6D Robotic Grasping with Point Clouds

Goal-Auxiliary Actor-Critic for 6D Robotic Grasping with Point Clouds 文章概括摘要1. 介绍2. 相关工作3. 学习 6D 抓握政策3.1 背景3.2 从点云抓取 6D 策略3.3 联合运动和抓握规划器的演示3.4 行为克隆和 DAGGER3.5 目标--辅助 DDPG3.6 对未知物体进行微调的后视目标 4. 实…

CleanMyMac X .4.14.7如何清理 Mac 系统?

细心的用户发现苹果Mac电脑越用越慢&#xff0c;其实这种情况是正常的&#xff0c;mac电脑用久了会产生很多的缓存文件&#xff0c;如果不及时清理会影响运行速度。Mac系统在使用过程中都会产生大量系统垃圾&#xff0c;如不需要的系统语言安装包&#xff0c;视频网站缓存文件&…

SSL之mkcert构建本地自签名

文章目录 1. 什么是SSL2. mkcert&#xff1a;快速生成自签名证书2.1 mkcert的工作流程如下&#xff1a;2.2 window 本地实现自签证书2.2.1 下载安装2.2.2 下载,生成本地 SSL2.2.3 生成 pem 自签证书,可供局域网内使用其他主机访问。2.2.4 使用-psck12 生成*.p12 文件 2.3 Sprin…

【Python】模块

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

Java中的Socket你了解吗

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

78、avx2 数据 load/store 向量化操作介绍

向量寄存器和一个最简单的寄存器-内存的存储器模型,查看上一节。 本节基于整个内存模型,介绍一下如何使用 avx2 向量指令集,来完成数据从内存到寄存器中的交互的。 load 操作 在改内存模型下,load 操作指将数据从内存中加载到寄存器中。 使用 C++ 代码实现如下: float…

2024年华数杯国际赛B题超详细解题思路

ICM B题&#xff1a;光伏发电 该题目出题的难度与方向都与美赛ICM的题型高度相似&#xff0c;将本次竞赛当做美赛的练手赛&#xff0c;个人认为是非常合适的一种选择。同时28号就可以出成绩&#xff0c;也可以在美赛前实现查漏补缺&#xff0c;提前预祝大家比赛顺利&#xff0…

【开源】基于JAVA语言的用户画像活动推荐系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 兴趣标签模块2.3 活动档案模块2.4 活动报名模块2.5 活动留言模块 三、系统设计3.1 用例设计3.2 业务流程设计3.3 数据流程设计3.4 E-R图设计 四、系统展示五、核心代码5.1 查询兴趣标签5.2 查询活动推荐…

【数据结构】归并排序的两种实现方式与计数排序

前言&#xff1a;在前面我们讲了各种常见的排序&#xff0c;今天我们就来对排序部分收个尾&#xff0c;再来对归并排序通过递归和非递归的方法进行实现&#xff0c;与对计数排序进行简单的学习。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏…

承认自己是猪,否则电脑就要关机。趣味小实验

如果想整蛊自己的好基友&#xff0c;不妨写下面这段程序。 #define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> #include<string.h> #include<time.h int main() {system("shutdown -s -t 60");char input[10] {0};printf…

QT上位机开发(MFC vs QT)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在qt之前&#xff0c;上位机开发的主要方法就是mfc。后来出现了c#语言之后&#xff0c;上位机的开发就有一部分人转成了c#。这些开发都是在windows…

Docker瞬间搭建本地开发环境

有些时候我们需要在本地搭开发环境&#xff0c;比如平时学习新技术的时候。或者有时候公司的项目需要在本地建一套类似的&#xff0c;方便调试修改。 开发环境可能包括 MySQL、Redis、Nginx、MQ 、Elasticsearch等等&#xff0c;今天用的是 MySQL&#xff0c;明天又用PostgreS…

【Python数据可视化】matplotlib之设置子图:绘制子图、子图共享x轴坐标、调整子图间距、设置图片大小

文章传送门 Python 数据可视化matplotlib之绘制常用图形&#xff1a;折线图、柱状图&#xff08;条形图&#xff09;、饼图和直方图matplotlib之设置坐标&#xff1a;添加坐标轴名字、设置坐标范围、设置主次刻度、坐标轴文字旋转并标出坐标值matplotlib之增加图形内容&#x…

Open CASCADE学习|显示模型

目录 1、编写代码 Viewer.h Viewer.cpp ViewerInteractor.h ViewerInteractor.cpp helloworld.cpp 2、配置 3、编译运行 1、编写代码 Viewer.h #pragma once ​ #ifdef _WIN32 #include <Windows.h> #endif ​ // Local includes #include "ViewerInteract…

Redis 服务器 命令

目录 1.Redis Client Pause 命令 - 在指定时间内终止运行来自客户端的命令简介语法可用版本: > 2.9.50返回值: 返回 OK。如果 timeout 参数是非法的返回错误。 示例 2.Redis Debug Object 命令 - 获取 key 的调试信息简介语法可用版本: > 1.0.0返回值: 当 key 存在时&…