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. CodeForces - 95E: Lucky Country (多重背包)

    pro:给定N个点,M条边,现在你要给一些连通块加边,使得至少存在一个连通块的大小是由4和7组成的数字.问至少加边数量. sol: 看似一个很难的题目.  首先不要想太难了,还是应该想能不能用背包做. ...

  2. 9、Python复杂数据类型(list、tuple、set、dict)

    一.列表(list):[a1,a2],可变数据类型 1.序列: 序列是基类类型,序列扩展类型包括:字符串.元组和列表 序列都可以进行的操作包括索引,切片,加,乘,检查成员. 此外,Python已经内置 ...

  3. windows——快速得到某一目录下所有文件的名称

    前言 其实用的是windows上dir命令,能快速得到某一目录下的所有文件名称,天天那么忙都没时间写博客(┬_┬) 步骤 打开cmd并cd到某目录下 C:\Users\Administrator.KI ...

  4. Log4net 数据库存储(四)

    1.新建一个空的ASP.Net 空项目,然后添加Default.aspx窗体 2.添加配置文件:log4net.config <?xml version="1.0" enco ...

  5. Mac OSX上安装SublimeText 3编译Processing 3.0

    1.安装SublimeText 32.使用Preferences - Package Control:Install Package - Processing安装 如果移动了Processing的位置 ...

  6. 58、Spark Streaming: DStream的output操作以及foreachRDD详解

    一.output操作 1.output操作 DStream中的所有计算,都是由output操作触发的,比如print().如果没有任何output操作,那么,压根儿就不会执行定义的计算逻辑. 此外,即 ...

  7. OpenFOAM——气泡上升

    计算域的顶部为大气,其余部分为壁面 流体的物性参数为: 首先进行建模操作,任何建模软件均可,本算例采用ICEM直接建模,生成网格,然后利用OpenFOAM下转化网格,划分完成的网格如下: 网格比较密集 ...

  8. CTF SSTI(服务器模板注入)

    目录 基础 一些姿势 1.config 2.self 3.[].() 3.url_for, g, request, namespace, lipsum, range, session, dict, g ...

  9. idea在docker环境,调试spring boot程序

    允许docker被远程访问 见:https://www.cnblogs.com/wintersoft/p/10921396.html 教程见:https://spring.io/guides/gs/s ...

  10. unity2019新建LWRP项目出错:Failed to resolve project template

    原因不详,但是在C盘创建项目的确会出现这个问题,改到D盘或E盘就没这个问题了