MONGODB 出现问题怎么查找问题,三板斧

2022-04-05 14:15:43 浏览数 (1)

NC这一阵子MONGODB 的需求起来了,但问题是之前没来之前也用MONGODB 但实际得情况是,不怎么样。运维的同事告诉我,MONGODB 在公司原来的情况可以用一句话来表达,有这么个东西。

上礼拜MONGODB 一个复制集出现问题,报出在短短的5分钟出现 6亿的访问,然后应用就挂了,对我没写错 6亿,个人认为这6亿的确是有问题,可人家一堆人的反馈是就是MONGODB 有问题。这边不表到底我怎么解决的这个问题,这里先说说,遇到这样得问题,我们怎么办。

第一斧,快速了解你的MONGODB 所处的负载情况

1 打开你的MONGODB 的

mongostat --host 192.168.198.100:27027 -uroot -p1234.Com --authenticationDatabase admin

系统会打开当前的MONGODB 的监控实时的状态

其中可以查看当前mongodb在间隔时间中获取的insert update query delete command的数量以及当时的系统中的内存状态,脏页刷新的状态等等,网络的数据进出的状态,连接的数量等等。

mongostat --host 192.168.198.100:27027 -uroot -p1234.Com --authenticationDatabase admin --discover

在mongodb的使用中,我们几乎很少使用除复制集之外的模式,所以在我们连接到一个复制集中的机器后,可以在通过 --discover 来在一个界面上展示三台或更多的主机的在同一个时刻的情况。

在这些列表的数据中,我们需要注意

1 res 物理内存的使用量

2 faults 当faults 中的数字较大的情况,一般根据具体数据库承载的数据量和内存的情况,如果每秒访问数据都是出于失败的状态,说明内存不足。

3 qr 客户端等待读取数据的列长度

4 qw 客户等待数据写入的队列的长度

2 通过定期获得这些数据可以分析出系统的运行情况。

1 另外在一些情况下可以写一些脚本通过系统来获取一些MONGODB 的运行得数据

1.1 当前系统的连接情况,db.serverStatus().connections

这里的current 是标记当前的系统正在连接的数字,这里包含正在工作的和idel的连接。同时 available 不是MONGODB还能接受多少连接,而是LINUX 系统本身还能接受多少连接,具体还有多少连接与 配置中设置的MaxIncomingConnections 有关,具体还能有多少连接是通过 maxcomingConnections - current得出的数字,active 为当前活跃正在工作的连接数字。

第二斧, 针对当前访问数据库的源地址,进行分类,将每个地址对数据库访问进行统计

代码语言:javascript复制
db.currentOp(true).inprog.reduce(
  (accumulator, connection) => {
    ipaddress = connection.client ? connection.client.split(":")[0] : "Internal";
    accumulator[ipaddress] = (accumulator[ipaddress] || 0)   1;
    accumulator["TOTAL_CONNECTION_COUNT"]  ;
    return accumulator;
  },
  { TOTAL_CONNECTION_COUNT: 0 }
)

下面是一个更详细的展示方式

代码语言:javascript复制
db.getSiblingDB("admin").aggregate( [
   { $currentOp: { allUsers: true, idleConnections: true, idleSessions: true } }
  ,{$project:{
            "_id":0
           ,client:{$arrayElemAt:[ {$split:["$client",":"]}, 0 ] }
           ,curr_active:{$cond:[{$eq:["$active",true]},1,0]}
           ,curr_inactive:{$cond:[{$eq:["$active",false]},1,0]}
           }
   }
  ,{$match:{client:{$ne: null}}}
  ,{$group:{_id:"$client",curr_active:{$sum:"$curr_active"},curr_inactive:{$sum:"$curr_inactive"},total:{$sum:1}}}
  ,{$sort:{total:-1}}
] )

对当前的数据库服务器的内存的分配情况进行列出

db.serverStatus().tcmalloc.tcmalloc.formattedString

或者我们可以通过更简单的方式来展示,当前的Mongodb使用数据内存的方式。

db.serverStatus().mem

另外影响系统性能的另一个需要注意的地方就是mongodb中的锁,这里面我们需要注意三种锁

1 全局锁

2 数据库锁

3 collection 锁

db.serverStatus().locks.Global db.serverStatus().locks.Database db.serverStatus().locks.Collection

通过锁定期获取数字的变化,查看系统的性能的影响是否与锁有关。

第三斧, 对数据库中的执行的语句开启慢查询,获取慢查询的语句,不同于其他数据库,MONGODB 的慢查询本身并不是敞开的,主要还是因为我们对MONGODB 的慢查询的要求比较苛刻,基本上500ms的查询我们就要认为是慢查询需要进行查看如果不是聚合的话,是要进行优化的。

1 到对应要收集慢查询的数据库中,打开慢查询

db.setProfilingLevel(1,{slowms:500}) #打开慢查询 db.system.profile.find().pretty() #查看慢查询语句的记录 db.setProfilingLevel(0) 关闭慢查询 db.getProfilingLevel(0) 查看慢查询是否开启

db.system.profile.drop()

db.createCollection( "system.profile", { capped: true, size:4000000 } ) db.setProfilingLevel(1,{slowms:500}) db.getProfilingLevel()

如果是第二次或频繁打开慢查询,可以将上次的慢查询内容清空,然后在初始化慢查询collection ,在打开慢查询接受慢查询语句。

db.currentOp({"secs_running": {$gte: 5}})

或者直接在系统的currentOp中查看当前是否有慢的语句在执行。

在获得慢查询后,可以通过下面的语句针对不同时间段的慢查询信息,或者以满语句前10的方式来查询慢查询数据。

db.system.profile.find().limit(10).sort({ts:-1}).pretty()

db.system.profile.find(                       {                         ts : {                               $gt : new ISODate("2021-07-12T03:00:00Z") ,                               $lt : new ISODate("2021-07-12T03:40:00Z")                              }                       },                       { user : 0 }                      ).sort( { millis : -1 } )

基于MONGODB 本身的简单的特性,在快速处理MONGODB 的方法本身不用很多,只要能很快的命中问题的关键点,在加以分析,就能很快的找到问题的发生的点。

0 人点赞