MongoDB CPU利用率很高,怎么破(转)
经常有用户咨询:MongoDB CPU 利用率很高,都快跑满了,应该怎么办?
遇到这个问题,99.9999% 的可能性是「用户使用上不合理导致」,本文主要介绍从应用的角度如何排查 MongoDB CPU 利用率高的问题。
Step1: 分析数据库正在执行的请求
用户可以通过 Mongo Shell 连接,并执行 db.currentOp() 命令,能看到数据库当前正在执行的操作,如下是该命令的一个输出示例,标识一个正在执行的操作。重点关注几个字段:
- client:请求是由哪个客户端发起的?
- opid:操作的opid,有需要的话,可以通过 db.killOp(opid) 直接干掉的操作;
- secs_running/microsecs_running: 这个值重点关注,代表请求运行的时间,如果这个值特别大,就得注意了,看看请求是否合理;
- query/ns: 这个能看出是对哪个集合正在执行什么操作;
- lock*:还有一些跟锁相关的参数,需要了解可以看官网文档,本文不做详细介绍。
{
"desc" : "conn632530",
"threadId" : "140298196924160",
"connectionId" : 632530,
"client" : "11.192.159.236:57052",
"active" : true,
"opid" : 1008837885,
"secs_running" : 0,
"microsecs_running" : NumberLong(70),
"op" : "update",
"ns" : "mygame.players",
"query" : {
"uid" : NumberLong(31577677)
},
"numYields" : 0,
"locks" : {
"Global" : "w",
"Database" : "w",
"Collection" : "w"
},
....
},
这里先要明确一下,通过 db.currentOp() 查看正在执行的操作,目的到底是什么?
并不是说我们要将正在执行的操作都列出来,然后通过 killOp 逐个干掉;这一步的目的是要看一下,是否有「意料之外」的耗时请求正在执行。
比如你的业务平时 CPU 利用率不高,运维管理人员连到数据库执行了一些需要全表扫描的操作,然后突然 CPU 利用率飙高,导致你的业务响应很慢,那么就要重点关注下那些执行时间很长的操作。
一旦找到罪魁祸首,拿到对应请求的 opid,执行 db.killOp(opid) 将对应的请求干掉。
如果你的应用一上线,cpu利用率就很高,而且一直持续,通过 db.currentOp 的结果也没发现什么异常请求,可以进入到 Step2 进行更深入的分析。
Step2:分析数据库慢请求
MongoDB 支持 profiling 功能,将请求的执行情况记录到同DB下的 system.profile 集合里,profiling 有3种模式:
- 关闭 profiling;
- 针对所有请求开启 profiling,将所有请求的执行都记录到 system.profile 集合;
- 针对慢请求 profiling,将超过一定阈值的请求,记录到system.profile 集合。
默认请求下,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)
在开启了慢请求 profiling 的情况下(MongoDB 云数据库是默认开启慢请求 profiling的),我们对慢请求的内容进行分析,来找出可优化的点,常见的包括。
CPU杀手1:全表扫描
全集合(表)扫描 COLLSCAN,当一个查询(或更新、删除)请求需要全表扫描时,是非常耗CPU资源的,所以当你在 system.profile 集合 或者 日志文件发现 COLLSCAN 关键字时,就得注意了,很可能就是这些查询吃掉了你的 CPU 资源;确认一下,如果这种请求比较频繁,最好是针对查询的字段建立索引来优化。
一个查询扫描了多少文档,可查看 system.profile 里的 docsExamined 的值,该值越大,请求CPU开销越大。
> 关键字:COLLSCAN、 docsExamined
CPU杀手2:不合理的索引
有的时候,请求即使查询走了索引,执行也很慢,通常是因为合理建立不太合理(或者是匹配的结果本身就很多,这样即使走索引,请求开销也不会优化很多)。
如下所示,假设某个集合的数据,x字段的取值很少(假设只有1、2),而y字段的取值很丰富。
{ x: 1, y: 1 }
{ x: 1, y: 2 }
{ x: 1, y: 3 }
......
{ x: 1, y: 100000}
{ x: 2, y: 1 }
{ x: 2, y: 2 }
{ x: 2, y: 3 }
......
{ x: 1, y: 100000}
要服务 {x: 1: y: 2} 这样的查询
db.createIndex( {x: 1} ) 效果不好,因为x相同取值太多;
db.createIndex( {x: 1, y: 1} ) 效果不好,因为x相同取值太多;
db.createIndex( {y: 1 } ) 效果好,因为y相同取值很少;
db.createIndex( {y: 1, x: 1 } ) 效果好,因为y相同取值少;
至于{y: 1} 与 {y: 1, x: 1} 的区别,可参考MongoDB索引原理 及 复合索引官方文档 自行理解。
一个走索引的查询,扫描了多少条索引,可查看 system.profile 里的 keysExamined 字段,该值越大,CPU 开销越大。
>关键字:IXSCAN、keysExamined
CPU杀手3:大量数据排序
当查询请求里包含排序的时候,如果排序无法通过索引满足,MongoDB 会在内存李结果进行排序,而排序这个动作本身是非常耗 CPU 资源的,优化的方法仍然是建立索引,对经常需要排序的字段,建立索引。
当你在 system.profile 集合 或者 日志文件发现 SORT 关键字时,就可以考虑通过索引来优化排序。当请求包含排序阶段时, system.profile 里的 hasSortStage 字段会为 true。
> 关键字:SORT、hasSortStage
其他还有诸如建索引,aggregationv等操作也可能非常耗 CPU 资源,但本质上也是上述几种场景;建索引需要全表扫描,而vaggeregation 也是遍历、查询、更新、排序等动作的组合。
Step3: 服务能力评估
经过上述2步,你发现整个数据库的查询非常合理,所有的请求都是高效的走了索引,基本没有优化的空间了,那么很可能是你机器的服务能力已经达到上限了,应该升级配置了(或者通过 sharding 扩展)。
当然最好的情况时,提前对 MongoDB 进行测试,了解在你的场景下,对应的服务能力上限,以便及时扩容、升级,而不是到 CPU 资源用满,业务已经完全撑不住的时候才去做评估。
来源:https://www.ywnds.com/?p=9010
文章来源:张友东的博客
MongoDB CPU利用率很高,怎么破(转)的更多相关文章
- [Oracle]Oracle数据库CPU利用率很高解决方案
Oracle数据库经常会遇到CPU利用率很高的情况,这种时候大都是数据库中存在着严重性能低下的SQL语句,这种SQL语句大大的消耗了CPU资源,导致整个系统性能低下.当然,引起严重性能低下的SQL语句 ...
- MongoDB优化之三:如何排查MongoDB CPU利用率高的问题
遇到这个问题,99.9999% 的可能性是「用户使用上不合理导致」,本文主要介绍从应用的角度如何排查 MongoDB CPU 利用率高的问题. Step1: 分析数据库正在执行的请求 用户可以通过 M ...
- 性能测试问题_Mysql数据库服务器的CPU占用很高
MySQl服务器CPU占用很高 1. 问题描述 一个简单的接口,根据传入的号段查询号码归属地,运行性能测试脚本,20个并发mysql的CPU就很高,监控发现只有一个select语句,且表建立了索引 ...
- 空循环导致CPU使用率很高
业务背景 业务背景就是需要将多张业务表中的数据增量同步到一张大宽表中,后台系统基于这张大宽表开展业务,所以就开发了一个数据同步工具,由中间件采集binlog消息到kafka里,然后我去消费,实现增量同 ...
- 记一次java应用cpu利用率过高调试经历
1,现象 写的一个storm应用,主要是通过mysql的binlog来同步表到hbase.运行一段时间后发现,经常会出现cpu使用率飙升到200%以上,然后各种消息堆积报警等等出现各种问题 2,调研过 ...
- 06 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
上一节我讲了 CPU 使用率是什么,并通过一个案例教你使用 top.vmstat.pidstat 等工具,排查高 CPU 使用率的进程,然后再使用 perf top 工具,定位应用内部函数的问题.不过 ...
- 06讲案例篇:系统的CPU使用率很高,但为啥却找不到高CPU的应用
小结 碰到常规问题无法解释的 CPU 使用率情况时,首先要想到有可能是短时应用导致的问题,比如有可能是下面这两种情况. 第一,应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过 top ...
- 4 系统的 CPU 使用率很高,但为啥却找不到高 CPU的应用?
上一节讲了 CPU 使用率是什么,并通过一个案例教你使用 top.vmstat.pidstat 等工具,排查高 CPU 使用率的进程,然后再使用 perf top 工具,定位应用内部函数的问题.不过就 ...
- MongoDB CPU使用较高,如何排查?
前言 首先,我们简单梳理一下,CPU 在什么情况下才算负载较高?负载查看是通过"uptime"命令查看.大家都知道,命令显示的结果分别表示1分钟.5分钟.15分钟的负载情况,这点就 ...
随机推荐
- unittest===unittest 的几种执行方式
#demo.py import requests import json class RunMain: def __init__(self, url, method, data=None): self ...
- Windows下启动、重启、停止nginx
在Windows下操作nginx,需要打开cmd 进入到nginx的安装目录下 1.启动nginx: start nginx 或 nginx.exe 2.停止nginx(stop是快速停止nginx, ...
- UltraEdit 替换符
1.在每行的最后一行添加字符串: 打开替换,在查找中输入 ^r 在替换栏中输入要替换的字符 再把下边的正则表达式勾选,然后开始或是全部替换就可以了 2.替换回车换行 在查找中输入 要替换的字符 ...
- SpringBoot读取Linux服务器某路径下文件\读取项目Resource下文件
// SpringBoot读取Linux服务器某路径下文件 public String messageToRouted() { File file = null; try { file = Resou ...
- 【Spring Boot学习之八】发布打包
环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 一.打jar类型1.指定主程序入口,否则运行报错:没有主清单属性pom.xml: <build> < ...
- [UE4] TSharedPtr, TWeakObjectPtr and TUniquePtr
转自:https://dawnarc.com/2018/07/ue4-tsharedptr-tweakobjectptr-and-tuniqueptr/ UE4 的 TSharedPtr.TWeakO ...
- k8s-ingress安装
一.编写nginx-ingress-controller.yaml文件 apiVersion: extensions/v1beta1 kind: Deployment metadata: name ...
- Google Adsense(谷歌网站联盟)广告申请指南
Google AdSense 是一种获取收入的快速简便的方法,适合于各种规模的网站发布商.它可以在网站的内容网页上展示相关性较高的 Google 广告,并且这些广告不会过分夸张醒目.由于所展示的广告同 ...
- Java之static作用的深度总结
1.深度总结 引用一位网友的话,说的非常好,如果别人问你static的作用:如果你说静态修饰 类的属性 和 类的方法 别人认为你是合格的:如果是说 可以构成 静态代码块,那别人认为你还可以: 如果你说 ...
- vs code 自定义配置记录
java环境安装:https://devblogs.microsoft.com/visualstudio/announcing-visual-studio-code-java-installer/ 保 ...