mongodb系列~具体案例

一  增加索引导致的性能问题

   1 问题描述

     分片环境,从库提供读写分离服务,在主库后台串行化添加完三个索引后,从库IO压力爆发,导致堆积了大量慢日志,由于程序获取不到结果不断尝试,导致总连接数耗尽

     增加索引具体流程

     1 主节点查询对应表数据,然后build构建索引。

     2   索引数据构建执行完成后,返回客户端OK。(注意:主构建完成后就通知OK给客户端,实际上这时候从节点还没有开始构建索引)

     3   生成createIndex对应oplog数据到oplog表

     4 从节点获取到createIndex对应oplog操作,然后重放createIndex构建索引。

   2 问题分析

     在从库获取oplog后,先执行第一个添加索引操作,还没完成就又添加了第二个第三个,导致出现了并行的情况.消耗了大量IO资源,导致后续的一系列情况

   3 问题解决

      1 kill相应mongo实例-这时候即便重启依然会执行构建索引操作

      2 mongod -f  mongod_20001.conf–noIndexBuildRetry  以noindexbuidlretry启动跳过重构索引 降低IO消耗

      3 也可以以去掉副本集参数 以单实例启动 增加索引,增加完再以副本集的成员加入集群

  4 问题避免

     1 升级版本 4.0X版本会顺序执行相关增加索引操作,做了优化

     2 避免连续执行大表的增加索引操作,或者一个增加索引操作完成后,确保secondary节点完成再执行下一个增加索引操作

     3 尽量不要在业务高峰期执行操作

二 慢日志优化汇总

    1 数组内元素查询需要使用 $elemMatch

      { "qList": { $elemMatch: { "qid": 1, "reorderFlag": 0} } }  aList为父 qid何reorderFlag为数组内元素

 三  global-lock突然上升-读写TICKET剩余量减少

      1 值获取

        db.serverStatus().globalLock

      2 获取顺序

         globalLock ==> DBLock ==> CollecitonLock  在globallock层次加的是意向锁,如果是读就是(MODE_IS) 如果是写就是(mode_IX) IS和IX是无需竞争的,所以读写请求可以在没有竞争的情况下,同时传到wiredtiger引擎去处理 ,获取不到ticket,global lock值就会升高

      3 如果globalLock.currentQueue.readers/writers个值长时间都不为0(此时globalLock.activeClients.readers/writers肯定是持续接近或等于128的),说明你的系统并发太高(或者有长时间占用互斥锁的请求比如前台建索引),可以通过优化单个请求的处理时间(比如建索引来减少COLLSCAN或SORT),或升级后端资源(内存、磁盘IO能力、CPU)来优化。

四  MONGODB统计表数据量的标准

      db.collections.count({"_id":{$exists:true}}

五 MONGO预备

   1 关闭NUMA 2 调整算法为 deadline(非SSD) 3 linux内核版本>2.6 xfs文件系统 4 关闭大页 

六 MONGO聚合内存不足

    内存限制大小是16M db.collection.aggregate([{$group:{_id:"$_id"}}], {allowDiskUse: true}) 添加allowDiskUse解决

原文地址:https://www.cnblogs.com/danhuangpai/p/15147958.html