一 增加索引导致的性能问题
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解决