本次直播视频精彩回顾,戳这里!
演讲嘉宾简介:
陈柯任(花名:莫归),阿里巴巴高级开发工程师,曾在大众点评从事MongoDB与MySQL相关运维和自动化研发,现就职于阿里云MongoDB团队,主要致力于分布式存储和NoSQL数据库相关领域。
以下内容根据演讲嘉宾视频分享以及PPT整理而成
本次分享主要围绕以下三个方面:
一.MongoDB指标分类及查看命令
二.关键指标详解
三.场景诊断
一.MongoDB指标分类及查看:
- MongoDB进程状态指标命令:db.serverStatus(),主要数据性能查看来源
- MongoDB数据文件状态指标命令: db.stats(), db.c.stats(),查看文件大小,存储空间大小等等
- MongoDB副本集状态指标命令: rs.status()
1. MongoDB数据文件状态指标解析:
db.stats()实际是一个语法糖,在底层实现是db.runCommand({dbstats:1,scale:scale})的命令,其中包含dbstats与scale两个参数,dbstats是输出值,scale可以控制输出值单位,一般默认dbstats为1,scale为byte,则此时以byte为单位输出dbstats。另一种方法db.c.stats()与db.stats()方法相同,在此不多做赘述。
以上为db.stats()调用出的数据库状态图片,共分以上指标,这其中不少同学曾对dataSize与storageSize的意义感到迷惑。事实上,dataSize指的是数据本身即未压缩时的大小,而storageSize则指的是数据落盘时的大小,数据在落盘时会执行一些相应的压缩算法,比如MongoDB本身默认的snappy压缩算法,压缩率在4到5倍之间,这便是为什么dataSize往往比storageSize大的原因。当使用者发现这两个数值相近时,很有可能是数据文件出现了文件空洞,这时建议使用者进行compact或者重搭一类的办法消除文件空洞。indexSize指标指的是索引落盘的大小,即索引的物理存储的大小。利用IndexSize与storageSize相加,我们就能得到对应数据库占用磁盘的大小,同时用dataSize除以storageSize我们可以判断压缩比的值,若压缩比值过小,很有可能出现了数据空洞,需要我们对其用compact命令进行处理。
2. MongoDB副本集状态指标解析:
3. MongoDB进程状态指标解析:(以MongoDB 3.4版本为例)
db.serverStatus()命令,即内部值db.runCommand(serverStatus:1,option)
option参数使得serverStatus()命令可以追加各种的filter,用以强制系统输出我们希望看到的数据。
二.关键指标详解:
下面我们对进程状态指标中比较重要的指标进行一一解读:
1. asserts:
asserts本身值得注意的事项较少,这其中asserts|user是一个很有趣的指标,它记录了用户执行命令错误的次数,如果该值较高,说明使用者命令记忆不清晰,建议多读一些指令文档。其他的一些值例如:asserts|msg,asserts|warning等通常为0值,当这些值不为0时,或多或少反映系统存在着某些问题。
2. connections:
connections指标标注的是连接的状况,其中available与current均显示的是当前的值,available表示数据库当前可用的连接量,当其值过低时,可能是出现了连接池过满的现象,通过改进数据库配置中的maxConnection或改善一些慢查询占用的连接可解决此问题。current表示数据库当前的连接数,当这个值高时,即出现了与available过低一样的问题,参考以上的解决方法同样可以解决此种问题。另一指标totalCreated记录了MongoDB启动后一共创建过多少个连接,通过采集工具做delta后我们可以得到每秒的创建量,当每秒的创建量过大时,说明我们的数据库采用了过多的短连进行连接,由于MongoDB基于线程模型的特点,过多的短连会使数据库的性能下降,希望大家多重视这个指标。
3. globalLock:
globalLock中的值同样表示的是当前的值,相较于connections, globalLock的值均由server内部的状态值中取出。其中activeClients主要描述了当前请求客户端操作锁的情况,currentQueue描述了当前进行有关锁的操作的队列情况,当这其中有过高指标时,说明我们的业务中正有大的有关锁部的操作影响着数据库的性能。
4. locks:
除了globalLocks,还有另一个指标locks同样负责描述数据库中锁的情况。大家会注意到在一些子指标中会有大写的”W,R”与小写的”w,r”。在这里,小写的r与w均为意向锁的意思,MongoDB的意向锁更像乐观锁,即虽然使用了锁但事实上并没有锁住数据。而我们真正需要关注的是大写的W与R,它们均为排它锁,它们的值也是累计值,通过它们每秒的增值,我们可以判断出我们系统的健康状况及业务访问的合理程度。子指标oplog的锁在从库上表现非常明显,当我们的从库触发apply oplog时,它会对oplog进行加锁。oplog是一个全局锁,当长时间触发时,会影响从库的读取,大家尽量保持主从库之间延迟处在较小的水平,反过来说当我们的从库读请求变慢时,我们也可以参考这个值判断是否是主从库延迟过大的问题。
5. network:
network是一个记录网络流量的累计值。bytesIn与bytesOut分别表示网络进口与网络出口流量,这些数据均已在MongoDB端被统计,physicalBytesIn与physicalBytesOut是3.4版本新加的指标,表示压缩后即物理实际进口流量及物理即压缩后出⼝流量。
6. opcounters:
opcounters是大家在使用过程中会经常参考的指标,是一个比较经典的监控指标 ,opcounters即为Op本身的一些QPS,其中command表示除了delete,getmore,insert,query,update以外,其他所有的操作命令,比如执行ServerStatus等这样一些操作,这个值也是累计值,我们通过采集它每秒的增量并将它们加和可以得到它真实的QPS,它的最大值是2的30次方,当系统运行时间过长该值超过2的30次方时,它会置为0值。大家有时会有这样的疑问:“为什么有时系统在某一时刻大量的超时,但QPS却并不高?”这是因为MongoDB的统计都是在操作执⾏完成之后才会生成,如果此时使用者的操作在MongoDB内部被锁住的话,这就造成了业务之间的时间差使得在这段时间内QPS不会增高,反而降低。
7. mem:
mem指标描述的大多数是内存中的状态。bits表示当前的MongoDB由多少位编译而成。resident表示常驻物理内存的大小,单位是兆。mem中的指标均为当前的值,大家取出来可以直接使用。
8. metrics:
metrics中的指标较多,而且不统一。metrics|command的指标大体可分为两类:metrics|command|failed记录了命令失败的总次数,metrics|command|total记录了命令执行的总次数,我们用total每秒的差值即可求得每秒执行命令的总次数。与前面讲的opcounters|command结合来看我们就可知道在一段时间内数据库中哪些命令执行的次数较多。下面的metrics|document|delete等指标为对文件的修改操作次数,也为累计值,同opcounters中的指标一样,也是在操作执⾏结束后才会记录。metrics|getLastError这类指标也是累计值,主要是在write大于1的模式下会使用到。其中metrics|getLastError|wtime|num指标表示写操作在w>1模式下getLastError需要等待其它节点应答的次数,metrics|getLastError|wtime|totalMillis表示写操作在w>1模式下getLastError需要等待其它节点应答的总时间,当这两个指标的除值即totalMillis/num的值过高时,说明平均写入同步延迟的时间过长,造成这种状态的原因可能是因为从结点的性能出现问题,导致整个集群性能的下降。
9. wiredTiger:
wiredTiger|cache|maximum bytes configured用来配置cache大小的指标,wiredTiger|cache|bytes currently in the cache表示当前cache使用大小的指标,二者相除,即可得到cache的使用率,tracked dirty bytes in the cache表示当前脏页大小,即我们写入或落盘的cache大小,写入大,如果是常态,可以适当提高dirty trigger。bytes read into cache与bytes written from cache指标是cache的读写量,它们的高低一般体现在我们磁盘的io读与io写上。concurrentTransactions是一个很有趣的指标,不知道大家平时是否有注意过?这个指标表示的是wiredTiger本身transaction控制的数量,这个值默认的是128个,当有一个请求时,会耗用一个transaction,在请求结束时,被耗用的值会被加回,当所有128个值被耗用光时,则从MongoDB层到所有引擎层的请求均会被block住,这些请求只有wiredTiger将持有的transaction释放掉时才会被执行。transaction checkpoint total time 指标也是一个累计值,它会在checkpoint结束之后才会进行计算该值,我们可以通过这个值计算checkpoint开始时间,并检查是否与系统发生问题的时间吻合。
三.场景诊断:
介绍了以上这么多指标,我们下面在使用场景中来看看它们是怎么应用的。
1. 当我们的客户端报错:client checkout connect timeout时
这种情况⼀般是客户端没有释放链接或者没有用连接池技术导致的,这时我们往往要看服务端与应用端的连接池情况。对于应用端来说,我们要关注connection.avaliable这个指标是否曾经出现过跌至0的情况,如上图所示,这是一张秒级监控图,在图中我们会发现虽然多数时间内avaliable指标会升满,但是有时该值还是会跌为0,在跌0的点,就一定会出现timeout的报错。通过这个指标的异常,我们可以采取在应用端使用一些连接池技术或检查一下是否存在连接没有释放等措施来进行一些优化。
2. 写入不断超时:
写入不断超时的情况是一个比较常见比较经典的情况了。当出现这种问题时,我们会发现我们数据库中的cache usage指标会不断飙高,有时也会出现transactions指标跌0的现象出现,此时明显我们的读写操作已无法继续执行。
四.总结