Mongodb CPU占用率达90%的优化调整报告
1问题描述
1.1现场的数据库部署情况
服务器基本情况如下:
|
CPU |
20逻辑核,40线程 |
|
内存 |
64 G |
|
硬盘 |
D盘 :1T SSD |
|
E盘:3T SATA |
|
|
F盘:3T SATA |
在这台机器上同时部署有postgresql和mongodb数据库。其中postgresql数据库存储入库后的矢量数据,mongodb存储矢量瓦片数据。
生成矢量切片的大致流程为:
- 查询mongodb数据库,检查哪些切片还未生成;
- 查询postgresql数据库,根据切片范围进行空间查询;
- 对第2)步查询结果进行切片处理,并将切片写入mongodb
1.2异常情况说明
刚开始作业时,效率尚可。然而当作业持续进行一段时间后,效率变得很低,甚至完全hang住不动了。同事分析,认为可能是postgresql空间查询效率过低导致。
2问题诊断
由于机器上部署有两个不同的数据库,并且,切片全流程会涉及到两个数据库。因此需要首先定位,到底慢在哪个数据库上?又或者,甚至还可能是操作系统级别的某种问题?
先通过性能监视器查看系统性能。一看就发现了问题,在切片程序hang住不动的时候,mongodb服务进程占用CPU的比率达到了90%以上,以至于服务器CPU负载长时间处于92%-99%。
首先定位到了是mongodb拖慢了速度,那么接下来,需要分析到底是mongodb中的什么操作拖慢了速度。
通过设置profile=1,slowms=100 ,并开启httpinterface option,然后在http://localhost:28017上监控mongodb中的log,发现了这样的一些日志信息:
-----------------------------------------------------------------------------------------------------------
……(省略若干行)
Command vindex.矢量瓦片测试_道路_线 command {count : "矢量瓦片测试_道路_线"} ,query :{fx:808 ,fy:189 ,flevel:10} } planSummary COLLSCAN keysExamined 0 docsExamined:2627694 numYields:20529 reslen:44 locks :{acquireCount :{r:41060}} ,MMAPV1Journal :{acquireCount :{r:20569}},Database :{acquireCount :{r:20530}},Collection:{acquireCount :{R:20530},acquireWaitCount : {R:39},timeAcquiringMicros:{R:}
……(省略若干行)
2017-01-17T17:32:11.816+0800 I COMMAND [conn187] vindex.矢量瓦片测试_道路_线 query: {$query: { flevel:3}, $orderby : {$natural:1}} planSummary : COLLSCAN ntoreturn : 500000 ntoskip:500000 keysExamined :0 docsExamined:3288241 cursorExhausted :1 numYields:25694 nreturned:0 reslen:20 locks:{ Global: {acquireCount :{r:51390}} ,MMAPV1Journal:{acquireCount: {r:25695}},Database:{ acquireCount:{r:25695}},Collection:{acquireCount:{R:25695}}} 8121ms
……(省略若干行)
-----------------------------------------------------------------------------------------------------------
先看第一条日志记录。一个简单的count查询,执行计划显示进行了COLLSCAN,即扫描集合。该次扫描扫描了个文档,然而返回的数据集只有44KB,另外,执行这样一次查询,获得锁的次数为41060,其中为了获得锁等待了39次。
再看第二条日志记录。这是一个query操作,查询结果进行了基于$natural(即基于数据在磁盘中的存储顺序)的排序。执行计划显示进行了COLLSCAN,即扫描集合。该查询使用了limit(500000).skip(500000)条件,为了获得500000个文档记录,共扫描了个文档,可是nreturned返回结果为0,说明查询了这么多,却没有符合条件的文档。另外,执行这样一次查询,获得锁的次数为51390。
分析到这里,问题已经很明显了。之所以发生这么多无效的扫描,原因在于集合中没有创建合适的索引,导致每次查询都要对集合进行扫描,而该集合目前已经达到了550GB的体量。
3调整方式
- 创建索引。
通过vindex.矢量瓦片测试_道路_线.ensureIndex({flevel:1,fx:1,fy:1}{unique:true})
方法创建基于flevel,fx,fy三列的唯一值索引;
- 修改query查询语句
第二条SQL中使用于基于$natural的排序,一般情况下使用$natural排序,是要告诉mongodb,本次查询不要使用索引。这样就意味着将从磁盘的顺序返回数据,强制mongodb不使用索引。它适用如这样一种场景:如果你创建了索引,但是要求返回大量的数据,通过索引来查询是很低效的,这时候你可以通过再sort中指定{"$natural":1}来强制不使用索引。而在本例中,flevel=3(还有flevel=4,flevel=5等)是从大量数据中返回极少量的数据,因此,使用$natural排序是不合适的。可将sort方式改为基于_id排序。
4调整后效果
在使用上述调整方式调整之后,服务器CPU使用率稳定在10%左右,切片进程不再出现hang住的情况。广东省整省数据,用1个小时就全部切片完毕。
5其它说明
尽管当前效率尚可,但通过mongostat进程监控mongodb服务器进程的性能发现,qw(队列中等待写的客户端进程数)达到30-50,说明在往mongodb中写的过程仍然存在很大的优化空间。改善写的性能,可以通过分片的技术手段解决。不过目前未在现场实施改造。其原因有二:
- 目前的切片效率满足要求,不需要另行改造
- 目前没有其它的服务器来部署分片架构
- 虽然当前服务器有3块可用磁盘(1.1现场的数据库部署情况),但通过HDTunePro的测试,发现两块SATA盘的iops仅为60-70左右,不适合用做数据库文件存储。因此,预计,即便在多块磁盘上实现了分片,也不会改善性能,甚至会降低性能。
Mongodb CPU占用率达90%的优化调整报告的更多相关文章
- 一次线上redis实例cpu占用率过高问题优化(转)
前情提要: 最近接了大数据项目的postgresql运维,刚接过来他们的报表系统就出现高峰期访问不了的问题,报表涉及实时数据和离线数据,离线读pg,实时读redis.然后自然而然就把redis也挪到我 ...
- redis实例cpu占用率过高问题优化
目录 一.简介 一.简介 前情提要: 最近接了大数据项目的postgresql运维,刚接过来他们的报表系统就出现高峰期访问不了的问题,报表涉及实时数据和离线数据,离线读pg,实时读redis.然后自然 ...
- maridb 10.3 主从复制,待机情况下从库 cpu 占用率高的处理方法
发现两台从库,一直都在CPU 占用率 60% 90% 中浮动, 但是写库却很正常.搜了一大把没找到答案,把参数测试了一下得出以下结论 slave my.cnf 添加如下参数 #只读模式 read_o ...
- 编程之美_1.1 让CPU占用率曲线听你指挥
听到有人说让要写一个程序,让用户来决定Windows任务管理器的CPU占用率. 觉得很好奇.但第一个想法就是写个死循环.哈哈.不知道具体的占用率是多少,但至少能保证在程序运行时,CPU的占用率终会稳定 ...
- Linux下如何查看高CPU占用率线程
转于:http://www.cnblogs.com/lidabo/p/4738113.html 目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidst ...
- linux top命令中各cpu占用率含义
linux top命令中各cpu占用率含义 [尊重原创文章摘自:http://www.iteye.com/topic/1137848]0.3% us 用户空间占用CPU百分比 1.0% sy 内核空间 ...
- Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算
目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidstat文件 procpidtasktidstat文件 系统中有关进程cpu使用率的常用命令 ps ...
- (转)linux top命令中各cpu占用率含义及案例分析
原文:https://blog.csdn.net/ydyang1126/article/details/72820349 linux top命令中各cpu占用率含义 0 性能监控介绍 1 确定应用类型 ...
- 1.1 让CPU占用率曲线听你指挥[cpu manager]
[本文链接] http://www.cnblogs.com/hellogiser/p/cpu-manager.html [题目] 写一个程序,让用户来决定Windows任务管理器(Task Manag ...
随机推荐
- assert 断言
输入 assert 1>2,'123' 输出结果 assert 1>2,'123' AssertionError: 123
- 【python】json中load和loads区别
相同点 dump 和 dumps 都实现了序列化 load 和 loads 都实现反序列化 变量从内存中变成可存储或传输的过程称之为序列化序列化是将对象状态转化为可保存或可传输格式的过程. 变量内容从 ...
- spring-cloud(一)
1.SpringCloud概述和搭建Eureka服务注册中心 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注 ...
- learning java Charset 查看支持的字符集类型
import java.nio.charset.Charset; import java.util.SortedMap; public class CharsetTest { public stati ...
- SVN 常用 还原项目
1.先修改本来两个文件,然后再提交到SVN 2.在日志界面,查看提交的文件,找到对应的版本号 3.找到对应的版本号(这里的版本号是1995,我提交生成的版本号 的前一个版本 才是我未作出修改的版本), ...
- 57、Spark Streaming: window滑动窗口以及热点搜索词滑动统计案例
一.window滑动窗口 1.概述 Spark Streaming提供了滑动窗口操作的支持,从而让我们可以对一个滑动窗口内的数据执行计算操作.每次掉落在窗口内的RDD的数据, 会被聚合起来执行计算操作 ...
- JavaScript中class类的介绍
class的概念 一.我们为什么要用到class类? 因为通过class类来创建对象,使得开发者不必写重复的代码,以达到代码复用的目的.它基于的逻辑是,两个或多个对象的结构功能类似,可以抽象出一个模板 ...
- Java-JUC(十四):SimpleDateFormat是线程不安全的
SimpleDateFormat是Java提供的一个格式化和解析日期的工具类,日常开发中应该经常会用到,但是由于它是线程不安全的,多线程公用一个SimpleDateFormat实例对日期进行解析.格式 ...
- 开启Nginx监控 with-http_stub_status_module
1.开启监控with-http_stub_status_module ./configure --with-openssl=/usr/local/ssl --with-http_stub_stat ...
- 蓝绿部署、A/B测试以及灰度发布(金丝雀发布)
过去的10多年里,很多大公司都在使用蓝绿部署,安全.可靠是这种部署方式的特点.蓝绿部署虽然算不上”Sliver Bullet“,但确实很实用.在有关于“微服务”.“DevOps”.“Cloud-nat ...