1问题描述

1.1现场的数据库部署情况

服务器基本情况如下:

CPU

20逻辑核,40线程

内存

64 G

硬盘

D盘 :1T SSD

E盘:3T SATA

F盘:3T SATA

在这台机器上同时部署有postgresql和mongodb数据库。其中postgresql数据库存储入库后的矢量数据,mongodb存储矢量瓦片数据。

生成矢量切片的大致流程为:

  1. 查询mongodb数据库,检查哪些切片还未生成;
  2. 查询postgresql数据库,根据切片范围进行空间查询;
  3. 对第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调整方式

  1. 创建索引。

通过vindex.矢量瓦片测试_道路_线.ensureIndex({flevel:1,fx:1,fy:1}{unique:true})

方法创建基于flevel,fx,fy三列的唯一值索引;

  1. 修改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中写的过程仍然存在很大的优化空间。改善写的性能,可以通过分片的技术手段解决。不过目前未在现场实施改造。其原因有二:

  1. 目前的切片效率满足要求,不需要另行改造
  2. 目前没有其它的服务器来部署分片架构
  3. 虽然当前服务器有3块可用磁盘(1.1现场的数据库部署情况),但通过HDTunePro的测试,发现两块SATA盘的iops仅为60-70左右,不适合用做数据库文件存储。因此,预计,即便在多块磁盘上实现了分片,也不会改善性能,甚至会降低性能。

Mongodb CPU占用率达90%的优化调整报告的更多相关文章

  1. 一次线上redis实例cpu占用率过高问题优化(转)

    前情提要: 最近接了大数据项目的postgresql运维,刚接过来他们的报表系统就出现高峰期访问不了的问题,报表涉及实时数据和离线数据,离线读pg,实时读redis.然后自然而然就把redis也挪到我 ...

  2. redis实例cpu占用率过高问题优化

    目录 一.简介 一.简介 前情提要: 最近接了大数据项目的postgresql运维,刚接过来他们的报表系统就出现高峰期访问不了的问题,报表涉及实时数据和离线数据,离线读pg,实时读redis.然后自然 ...

  3. maridb 10.3 主从复制,待机情况下从库 cpu 占用率高的处理方法

    发现两台从库,一直都在CPU 占用率 60% 90% 中浮动, 但是写库却很正常.搜了一大把没找到答案,把参数测试了一下得出以下结论 slave  my.cnf 添加如下参数 #只读模式 read_o ...

  4. 编程之美_1.1 让CPU占用率曲线听你指挥

    听到有人说让要写一个程序,让用户来决定Windows任务管理器的CPU占用率. 觉得很好奇.但第一个想法就是写个死循环.哈哈.不知道具体的占用率是多少,但至少能保证在程序运行时,CPU的占用率终会稳定 ...

  5. Linux下如何查看高CPU占用率线程

    转于:http://www.cnblogs.com/lidabo/p/4738113.html 目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidst ...

  6. linux top命令中各cpu占用率含义

    linux top命令中各cpu占用率含义 [尊重原创文章摘自:http://www.iteye.com/topic/1137848]0.3% us 用户空间占用CPU百分比 1.0% sy 内核空间 ...

  7. Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算

    目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidstat文件 procpidtasktidstat文件 系统中有关进程cpu使用率的常用命令 ps ...

  8. (转)linux top命令中各cpu占用率含义及案例分析

    原文:https://blog.csdn.net/ydyang1126/article/details/72820349 linux top命令中各cpu占用率含义 0 性能监控介绍 1 确定应用类型 ...

  9. 1.1 让CPU占用率曲线听你指挥[cpu manager]

    [本文链接] http://www.cnblogs.com/hellogiser/p/cpu-manager.html [题目] 写一个程序,让用户来决定Windows任务管理器(Task Manag ...

随机推荐

  1. learning java 处理流的用法

    有点重定向使用的味道 import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.Pri ...

  2. WinDbg常用命令系列---.cordll (控制CLR调试)

    .cordll (控制CLR调试) 简介 .cordell命令控制托管代码调试和Microsoft.NET公共语言运行库(CLR). 使用形式 .cordll [Options] 参数 Options ...

  3. CLR内部异常(上)

    当我们提到CLR里的“异常”,要注意一个很重要的区别.有通过如C#的try/catch/finally暴露给应用程序,并由运行时提供机制全权实现的托管异常.也有运行时自己使用的异常.大部分运行时开发人 ...

  4. Centos 不重启 修改ulimit参数

    1. 查看limits.conf文件 cat /etc/security/limits.conf 2. 打开编辑limits.conf文件 sudo vim /etc/security/limits. ...

  5. 事务控制语言(TCL)

    一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行.如:转账. 原子性(Atomicity):一个事务要么都执行,要么都回滚(不可再分割) 一致性(Consistency) ...

  6. P3709 大爷的字符串题(莫队+结论)

    题目 P3709 大爷的字符串题 做法 有一个显然的结论:一段区间里最小答案为众数的个数 用莫队来离线求众数 \(tmp_i\)表示出现\(i\)次的数的个数,\(num_i\)表示\(i\)出现的次 ...

  7. nRF51822 配对之device_manager_init 调用,以及保证 用户数据存储 的Flash 操作不与device manager 模块冲突

    昨天 遇到了一个烦心的问题,被老外客户怼了两句,恼火,很想发火,发现英文不够用,算了,就不跟直肠的鬼佬一般见识.说正事. 最近的一个nRF51822+MT2503 钱包防丢项目,准备接近量产了.昨天做 ...

  8. Linux命令及作用

    uname -r :查看当前使用的Linux内核版本信息 cat /proc/cpuinfo:查看当前主机CPU型号,规格等信息 cat /proc/meminfo :查看当前主机内存信息 hostn ...

  9. 2D转换模块

    2D转换模块(transform) 1.取值:rotate(45deg)--- 旋转,默认以自己为中心作为参考点来旋转 .translate(100px,0px)--- 平移,第一个参数代表水平方向, ...

  10. mongodb设置 十个要点

    mongodb设置 十个要点   一.对象ID的生成 每一个mongoDB文档那个都要求有一个主键.它在每一个集合中对全部的文档必须是唯一的.主键存放在文档_id字段中.由12个字符组成: 4c291 ...