2024-06-22 03:50:57
2024-06-22 11:06:53
【概述】
1)内存是否充足.
2)(BTree 树)索引不命中所占百分比.
3)全局写入锁占用了机器多少时间。发生全局写入锁时,所有查询都将等待,直到锁解除.
4)等待处理的查询请求队列大小.
5)监测当前连接数.
【MongoDb性能优化介绍】
A)MongoDb查询慢,性能不好的监测点。
mongostat:
A1)faults/s:每秒访问失败数,
即数据被交换出物理内存,放到SWAP。若过高(一般超过100),则意味着内存不足。
vmstat & iostat & iotop
[注]
si:每秒从磁盘读入虚拟内存的大小,若大于0,表示物理内存不足。
so:每秒虚拟内存写入磁盘的大小,若大于0,同上。
A2) idx miss %:BTree 树未命中的比例,即索引不命中所占百分比.
若过高,则意味着索引建立或使用不合理。
db.serverStatus()
indexCounters” : {
“btree” : {
“accesses” : 2821726, #索引被访问数
“hits” : 2821725, #索引命中数
“misses” : 1, #索引偏差数
“resets” : 0, #复位数
“missRatio” : 3.543930204420982e-7 #未命中率
}
A3)locked %:全局写入锁占用了机器多少时间.
当发生全局写入锁时,所有查询操作都将等待,直到写入锁解除。
若过高(一般超过50%),则意味着程序存在问题。
db.currentOp()
{
“inprog” : [ ],
“fsyncLock” : 1, #为1表示MongoDB的fsync进程(负责将写入改变同步到磁盘)不允许其他进程执行写数据操作
“info” : “use db.fsyncUnlock() to terminate the fsync write/snapshot lock”
}
A4)q r|w :等待处理的查询请求队列大小.
若过高,则意味着查询会过慢。
db.serverStatus()
“currentQueue” : {
“total” : 1024, #当前需要执行的队列
“readers” : 256, #读队列
“writers” : 768 #写队列
}
A5)conn :当前连接数.
高并发下,若连接数上不去,则意味着Linux系统内核需要调优。
db.serverStatus()
“connections” : {
“current” : 3, #当前连接数
“available” : 19997 #可用连接数
}
A6)连接数使用内存.
cat /proc/$(pidof mongod)/limits | grep stack | awk -F ‘size‘ ‘{print int($NF)/1024}‘
将连接数使用Linux栈内存设小,默认为10MB(10240)
shell> ulimit -s 1024
B)查看执行计划,并分析结果。
B1)优化器的设置。
db.setProfilingLevel(2);
0 – 不开启
1 – 记录慢命令 (默认为>100ms)
2 – 记录所有命令
info: #本命令的详细信息
reslen: #返回结果集的大小
nscanned: #本次查询扫描的记录数
nreturned: #本次查询实际返回的结果集
millis: #该命令执行耗时(毫秒)
B2)监控一个集合时一般关注的信息有哪些?.
集合 collect_x 未建立有效索引(建议考虑使用组合索引)
存在大量慢查询,均为collect_x读操作,且响应超过1秒
每次读操作均为全集合扫描,意味着耗用CPU(25% * 8核)
每次返回的记录字节数近1KB,建议过滤不必要的字段,提高传输效率。
B3)如何查询执行计划?
>db.Book.find({CharsCount: “200000”}).hint({CharsCount:1 }).explain();
B4)分析查询计划。
分析案例1)
[注]
cursor: 返回游标类型(BasicCursor 或 BtreeCursor)
nscanned: 被扫描的文档数量
n: 返回的文档数量
millis: 耗时(毫秒)
indexBounds: 所使用的索引.