1:想知道哪些操作拖慢了MongoDB的速度,首先需要检查当前正在执行哪些操作。
gechongrepl:PRIMARY> db.currentOp()
"opid" : 78891,#操作的唯一标识符,可通过它来终止操作 "active" : true,#true表示当前正在运行,false表示此操作已交出或在等待其他操作交出锁 "secs_running" : 1,#查看执行时间,可以通过该参数定位耗时的操作 "microsecs_running" : NumberLong(1081719),# "op" : "getmore",#操作的类型,有查询、插入、更新、删除。数据库命令当查询处理 "ns" : "local.oplog.rs", "query" : { }, "client" : "192.168.91.132:55738", "desc" : "conn1534",#可与日志信息联系起来,可以用来筛选相关的日志信息。 "threadId" : "0x7f91d77a5700", "connectionId" : 1534, "waitingForLock" : false,#表示该操作是否因正在等待其他操作交出锁而处于阻塞状态。 "numYields" : 0,#表示该操作交出锁,而使其他操作得以运行 "lockStats" : { "timeLockedMicros" : { "r" : NumberLong(68), "w" : NumberLong(0) }, "timeAcquiringMicros" : {#表示该操作需要多长时间才能取得所需的锁 "r" : NumberLong(7), "w" : NumberLong(0) } }
条件查询
gechongrepl:PRIMARY> db.currentOp({"ns":"local.oplog.rs"})
这里只是举个例子:通常不会终止ns:local.oplog.rs的,因为复制的线程会持续的向同步源请求更多的操作。如果被异常终止,MongoDB会重启他们,但是会短暂的中断复制。
如果发现特别耗时的查询可以终止操作
gechongrepl:PRIMARY> db.killOp(5299)
update和find和remove操作可以被终止。因为他们已经交出了锁。正在占用锁或者等待其他操作交出锁的操作则无法被终止
怪异现象:终止了一个批量插入的语句,最后发现还是插入完成了。因为批量插入操作请求之后会写在缓冲区中的。即使终止了客户端发送请求,MongoDB还会处理缓冲区的写入操作。如果需要解决这种现象最好的方式是使用应答式写入,即每次写入操作都会等待上一次写入操作完成后才会进行下去。
2:打开系统分析器
查看当前的分析器级别:
gechongrepl:PRIMARY> db.getProfilingLevel()
gechongrepl:PRIMARY> db.setProfilingLevel(2) { "was" : 0, "slowms" : 100, "ok" : 1 }
db.system.profile.find().pretty()
把级别设置为2意味着分析器会记录所有内容。数据库的所有读写请求都会写到system.profile中。这样会造成性能的损失,因为每一次写操作都会增加额外的写入时间,而每一次读操作都要等待写锁(因为它必须在system.profile集合中写入记录)
gechongrepl:PRIMARY> db.setProfilingLevel(1,100) { "was" : 2, "slowms" : 100, "ok" : 1 }
db.system.profile.find().pretty()
级别1分析器会默认记录耗时大于100ms的操作。可以自定义阀值
gechongrepl:PRIMARY> db.setProfilingLevel(1,500) { "was" : 1, "slowms" : 100, "ok" : 1 } db.system.profile.find().pretty()
gechongrepl:PRIMARY> db.setProfilingLevel(0) { "was" : 1, "slowms" : 500, "ok" : 1 }
0就是关闭分析器
3:计算MongoDB的空间消耗
_id存储为ObjectId类型,比存储为字符串类型效率更高
gechongrepl:PRIMARY> Object.bsonsize({_id:ObjectId()}) 22 gechongrepl:PRIMARY> Object.bsonsize({_id:""+ObjectId()}) 39
也可以直接对集合中的文档进行查询: gechongrepl:PRIMARY> Object.bsonsize(db.users.findOne()) 0
查看集合大小
gechongrepl:PRIMARY> db.test.stats() { "ns" : "test.test", "count" : 239000, "size" : 19728112, "avgObjSize" : 82, "storageSize" : 37797888, "numExtents" : 8, "nindexes" : 1, "lastExtentSize" : 15290368, "paddingFactor" : 1, "systemFlags" : 1, "userFlags" : 1, "totalIndexSize" : 7456512, "indexSizes" : { "_id_" : 7456512 }, "ok" : 1 } gechongrepl:PRIMARY>
以MB为单位显示
gechongrepl:PRIMARY> db.test.stats(1024*1024) { "ns" : "test.test", "count" : 239000, "size" : 18, "avgObjSize" : 82, "storageSize" : 36, "numExtents" : 8, "nindexes" : 1, "lastExtentSize" : 14, "paddingFactor" : 1, "systemFlags" : 1, "userFlags" : 1, "totalIndexSize" : 7, "indexSizes" : { "_id_" : 7 }, "ok" : 1 }
数据库大小:
gechongrepl:PRIMARY> db.stats() { "db" : "test", "collections" : 6, "objects" : 239035, "avgObjSize" : 82.56948145669044, "dataSize" : 19736996, "storageSize" : 38879232, "numExtents" : 13, "indexes" : 3, "indexSize" : 7472864, "fileSize" : 67108864, "nsSizeMB" : 16, "dataFileVersion" : { "major" : 4, "minor" : 5 }, "extentFreeList" : { "num" : 0, "totalSize" : 0 }, "ok" : 1 }
4:使用mongostat和mongotop查看