MongoDB调优

news2024/11/28 16:28:26

三大导致 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.coloradmin.cn/o/1392615.html

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

相关文章

Template Engine-06-模板引擎 Handlebars 入门介绍

拓展阅读 java 表达式引擎 logstash 日志加工处理-08-表达式执行引擎 AviatorScriptMVELOGNLSpELJEXLJUELJanino QLExpress 阿里表达式引擎系统学习 什么是 Handlebars? Handlebars 是一种简单的模板语言。 它使用模板和输入对象生成 HTML 或其他文本格式。Ha…

C Primer Plus 第6版 编程练习 chapter 15

文章目录 1. 第1题1.1 题目描述1.2 编程源码1.3 结果显示 2. 第2题2.1 题目描述2.2 编程源码2.3 结果显示 3. 第3题3.1 题目描述3.2 编程源码3.3 结果显示 4. 第4题4.1 题目描述4.2 编程源码4.3 结果显示 5. 第5题5.1 题目描述5.2 编程源码5.3 结果显示 6. 第6题6.1 题目描述6.…

使用easyexcel 导出多级表头demo

先看效果&#xff1a; 1、引入maven依赖 <!--EasyExcel --> <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.1</version> </dependency> 2、实体类 package com.…

c语言 编译与链接

编译与链接 翻译环境和执行环境翻译环境1.1预编译1.2编译1.3汇编&#xff08;ASM&#xff09;2.链接 执行环境最后给大家附上一张关于本节知识内容的图供大家更好理解~ ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/522d488885ba44d99aa504d6b21c88d5.png) &…

yolov8+deepsort的代码实现

按照官方描述&#xff0c;YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c;以进一步提升性能和灵活性。具体创新包括一个新的骨干网络、一个新的 Ancher-Free 检测头和一个新的损失函数&#xff0c;可以…

Python新手常见问题——列表中删不掉的0

1.测试代码 运行代码 nums1 [1,2,3,0,0,0] print(type(nums1))for i in nums1:if i 0:nums1.remove(i) print(nums1)效果如下 2.疑问&#xff1a; 上面代码&#xff0c;为什么把nums1里面的0移除不干净 3.原因&#xff1a; 在 Python 中&#xff0c;不建议在循环中直接…

蒙特卡洛概率抽样简介

蒙特卡罗方法是一类对概率分布进行随机抽样的技术。 在许多问题领域中&#xff0c;描述或估计概率分布相对简单&#xff0c;但计算所需的数量却很棘手。这可能是由于多种原因造成的&#xff0c;例如domain的随机性质或随机变量的指数级数量增长。 相反&#xff0c;可以通过使…

学校智慧能源消耗管理系统,破解学校节能降耗难题

随着碳达峰、碳中和工作的主要任务&#xff0c;学校作为能源集中地&#xff0c;且能源情况较为复杂的建筑&#xff0c;有效降低能源消耗、减少能源使用成本&#xff0c;已经成为学校一项紧迫的任务。 学校能耗痛点有哪些&#xff1f; 1、规模大 学校是集教学、科研、生活于一…

zabbix客户端配置及自定义监控

部署zabbix客户机 1.服务端和客户端都配置时间同步 yum install -y ntpdate ntpdate -u ntp.aliyun.com 2.服务端和客户端都设置 hosts 解析 cat > /etc/hosts << EOF 172.16.23.16 localhost 172.16.23.17 zbx-server EOF 3.被监控端 //设置 zabbix 的下载源&…

leedcode刷题笔记day1

题目大意&#xff1a; 暴力解法 两个for循环&#xff08;也是我一看到题目想到的方法&#xff09; 枚举在数组中所有的不同的两个下标的组合逐个检查它们所对应的数的和是否等于 target 复杂度分析 时间复杂度:O(n2)&#xff0c;这里 n 为数组的长度 空间复杂度:O(1)&#x…

精彩推荐 | 【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器开发实战指南(实战技术总结)

Dockerfile实战总结 前提介绍实战总结方案创建容器时传入环境变量调整宿主机和容器的时间差异解决办法 指定容器的rootfs的大小快速管理容器和镜像快速删除容器的原理--format格式化输出输出所有容器的name输出所有容器名包含test的容器查看退出状态的容器删除所有容器删除/启动…

transbigdata笔记:其他方法

1 出租车相关 1.1 taxigps_to_od 提取出租车OD信息 transbigdata.taxigps_to_od(data, col[VehicleNum, Stime, Lng, Lat, OpenStatus]) 输入出租车GPS数据&#xff0c;提取OD信息 data出租车GPS数据col[VehicleNum, Time, Lng, Lat, OpenStatus]五列 比如GPS数据长这样&am…

docker screen 常用基础命令

1.docker基础命令 1.1开启docker systemctl start docker #开启docker service docker restart #重启docker systemctl stop docker #关闭docker 1.2查看命令 docker images #查看docker镜像docker ps #查看正在运行的镜像或者容器docker ps -a #查看所有容器1.3运…

信驰达科技参与《汽车玻璃集成UWB数字钥匙发展研究白皮书》编制工作

为进一步探索汽车数字钥匙技术路线及开发思路&#xff0c;中国智能网联汽车产业创新联盟&#xff08;CAICV&#xff09;、福耀玻璃工业集团股份有限公司联合发起了《汽车玻璃集成UWB数字钥匙发展研究白皮书》研究工作。 2023年12月20日&#xff0c;由中国智能网联汽车产业创新…

Linux:/proc/kmsg 与 /proc/sys/kernel/printk_xxx

目录 前言一、/proc/kmsg1、简介2、如何修改内核日志缓冲区3、dmesgklogctl 函数&#xff08;来源于 man 手册&#xff09; 4、扩展阅读 二、 /proc/sys/kernel/printk_xxx三、/dev/kmsg 前言 本篇文章将为大家介绍与 Linux 内核日志相关的一些控制文件&#xff0c;共同学习&am…

C语言总结十二:文件操作详细总结

在操作系统中&#xff0c;为了统一对各种硬件的操作&#xff0c;简化接口&#xff0c;不同的硬件设备也都被看成一个文件。对这些文件的操作&#xff0c;等同于对磁盘上普通文件的操作。我们不去探讨硬件设备是如何被映射成文件的&#xff0c;把任意 I/O 设备&#xff0c;转换成…

ResNet论文翻译和精读

1:论文原文 论文原文&#xff1a; ResNet 2&#xff1a;该论文解决了什么问题&#xff1f; 改论文解决了深层的神经网络训练时的梯度消失和梯度爆炸的问题&#xff1b; 3&#xff1a;该论文的创新点&#xff1f; 将快捷连接应用到了网络中构建成了残差网络块&#xff1b;…

【嘉立创EDA-PCB设计指南】3.网络表概念解读+板框绘制

前言&#xff1a;本文对网络表概念解读板框绘制&#xff08;确定PCB板子轮廓&#xff09; 网络表概念解读 在本专栏的上一篇文章【嘉立创EDA-PCB设计指南】2&#xff0c;将设计的原理图转为了PCB&#xff0c;在PCB界面下出现了所有的封装&#xff0c;以及所有的飞线属性&…

代码随想录算法训练营29期|day 22 任务以及具体安排

235. 二叉搜索树的最近公共祖先 class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root null) return null;//向左遍历if(root.val > p.val && root.val > q.val){TreeNode left lowestCommonAncestor(roo…

Redis和MySQL如何保持数据一致性

前言 在高并发的场景下&#xff0c;大量的请求直接访问Mysql很容易造成性能问题。所以&#xff0c;我们都会用Redis来做数据的缓存&#xff0c;削减对数据库的请求。但是&#xff0c;Mysql和Redis是两种不同的数据库&#xff0c;如何保证不同数据库之间数据的一致性就非常关键…