前言

在探索 MongoDB 性能监控的过程中,我爬了一堆文章,最后总结一系列我认为很重要的关键指标,本文将借着实务经验分享我们该如何使用各项查询指令,并分析这些关键指标代表什么意义,帮助我们了解系统运行状况,及早发现潜在问题并及时採取优化措施。

基础资料概况

透过 db.rawdata.stats() 检视集合的基本资讯:

{
count: 3109528, // 文件总数
size: 22859420160, // 原始数据大小(约 21.3 GB)
avgObjSize: 7351, // 平均每笔文件大小(约 7.2 KB)
storageSize: 3371008000, // 实际存储大小(约 3.14 GB)
totalIndexSize: 63892480, // 索引总大小(约 61 MB)
nindexes: 2 // 索引数量
}

  • 原始数据量 21.3 GB 经过压缩后仅佔用 3.14 GB 的存储空间,实现了约 6.8:1 优异的压缩比。
  • 索引大小维持在 61 MB,相对于数据总量来说相当合理,表明索引设计十分精简。

系统记忆体使用分析

通过 db.serverStatus().mem 检视系统记忆体使用情况:

{
bits: 64,
resident: 5813, // 实际使用的实体记忆体(约 5.8 GB)
virtual: 6266, // 虚拟记忆体使用量(约 6.3 GB)
supported: true
}

  • 在配置 16 GB RAM 的作业系统中,MongoDB 实际使用了 5.8 GB 的实体记忆体,约占系统总记忆体的 36%。
  • 虚拟记忆体使用量略高于实体记忆体,显示系统正在有效地使用记忆体映射机制。

WiredTiger 引擎运行状态

通过 db.serverStatus().wiredTiger 检视存储引擎效能指标:

1. 快取管理(Cache)

cache: {
\'maximum bytes configured\': 8589934592, // 配置的最大快取大小(8 GB)
\'bytes currently in the cache\': 6442450944,// 当前使用的快取(6 GB)
\'pages requested from the cache\': 11958296,// 快取页面请求总数
\'pages read into cache\': 203920, // 从磁盘读入的页面数
\'pages written from cache\': 423890, // 写入磁盘的页面数
\'modified pages evicted\': 156789, // 被逐出的已修改页面数
\'unmodified pages evicted\': 234567 // 被逐出的未修改页面数
}

  • 目前系统配置8GB的最大快取空间,实际使用6GB,使用率约为75%(值得观察是否需要调高快取容量)。
  • 快取命中率可以通过以下计算得出:(11958296 - 203920) / 11958296 = 98.3%。这个极高的命中率表明目前预设的快取策略非常有效,绝大多数请求都能直接从快取中得到满足,极大地减少了磁盘I/O操作。

2. 连接状态(Connection)

connection: {
\'total read I/Os\': 3109528, // 总读取操作次数(与文件数相当)
\'total write I/Os\': 89756, // 总写入操作次数
\'total fsync I/Os\': 15678, // 档案同步操作次数
\'total read time (usecs)\': 892345,
\'total write time (usecs)\': 234567
}

  • 连接状态显示系统为典型的读取密集型工作负载,读写比例约为 35:1(3109528 : 89756)。
  • 平均读取时间为0.287微秒(892,345/3,109,528),而平均写入时间为2.613微秒(234,567/89,756),代表系统读写的效率也是十分优异。

3. 游标操作(Cursor)

cursor: {
\'cursor create calls\': 3893410, // 游标创建次数(约为文件数的 1.25 倍)
\'cursor next calls\': 15547640, // 游标遍历次数(约为文件数的 5 倍)
\'cursor search calls\': 3109528, // 精确查询次数(与文件数相当)
\'cursor search near calls\': 1554764 // 范围查询次数(约为文件数的 0.5 倍)
}

  • 游标操作统计反映出系统的查询模式特徵,每个文件平均被遍历 5 次,代表存在着大量遍历读取操作,这部分在上一篇分享到如何利用索引的建立优化查询效率。

4. 事务处理(Transaction)

transaction: {
\'transaction begins\': 567890,
\'transaction commits\': 456789,
\'transaction rollbacks\': 12345,
\'transactions rolled back by conflict\': 234
}

  • 在总计567,890次交易开始中,成功提交了456,789次,完成率约为80.4%。这个完成率反映了系统在处理交易时保持了较好的稳定性。然而,仍有约19.6%的交易未能成功完成,这个比例值得关注。
  • 在所有回滚的交易中(12,345次),仅有234次是由于冲突导致的,佔回滚总数的1.9%。这个较低的冲突率表明系统的并发控制机制运作良好,极少出现资源竞争情况。

小结

好的,明明是因为系统曾经出现 oom-kill (记忆体使用达上限导致服务强制中断),才开启我的优化之路的,结果现在却是机制良好、运作顺畅?!

其实是因为我写这篇文章时,并不是用量尖峰时期,那要怎么观察用量尖峰的状态呢?

下一篇我会写如何实作 MongoDB 简易的监控方式,帮助我们捕捉到尖峰时的崩溃是怎么发生的,进而採取下一步调整,敬请期待!