故障排除 Databases for MongoDB
本指南可帮助您识别和解决在 IBM Cloud 上运行并由 MongoDB 支持的 Databases for MongoDB 部署中的性能问题。
您还可以在下面找到有关解决性能问题的更多信息:
如果您的应用程序遇到响应缓慢、超时或数据库性能不一致的问题,请考虑以下步骤和信息。
性能问题的症状
您可能会观察到以下症状,这些症状表明性能出现了问题:
- 应用程序延迟增加
- 查询日志记录缓慢
- CPU 或内存使用率高
- 磁盘延迟增加
- 复制延迟
- 连接超时数
完成以下步骤以确定问题的原因:
步骤 1:检查资源利用情况
-
登录 IBM Cloud 控制台并导航至 MongoDB 部署。
-
审查监测部分,以了解
- CPU 利用率
- 内存使用率
- 磁盘 IOPS 和延迟
- 活动连接数
需要注意什么?
- CPU 始终高于 75
- 内存始终保持在 80% 以上
- 磁盘延迟随着时间推移而增加
- 接近计划限额的连接
建议采取的行动:
- 如果磁盘延迟较高,则增加存储或 IOPS。
- 查看应用程序中的工作量峰值。
如果资源使用量持续升高,建议进行扩展。
步骤 2:识别慢速查询
查询速度慢是导致性能下降的最常见原因之一。
-
启用剖析:
db.setProfilingLevel(1, { slowms: 100 }) -
回顾最近的缓慢行动:
db.system.profile.find().sort({ ts: -1 }).limit(20) -
分析查询执行情况:
db.collection.find({ ... }).explain("executionStats")
需要注意什么?
COLLSCAN(使用集合扫描代替索引)- 高
totalDocsExamined相比nReturned
建议采取的行动:
- 创建适当的索引。
- 使用复合索引进行多字段查询。
- 确保聚合管道从
$match开始。 - 避免使用大型
skip()分页。
步骤 3:审查连接使用情况
连接数过高或管理不善都会影响性能。
检查连接统计数据:
db.serverStatus().connections
建议采取的行动:
- 在应用程序中使用连接池。
- 避免每次请求都打开一个新连接。
- 关闭未使用的光标
连接限制由您的部署计划决定。
步骤 4:检查复制健康状况
复制延迟会影响读取性能和数据新鲜度。
检查复制状态:
rs.printSecondaryReplicationInfo()
滞后的常见原因:
- 高写入吞吐量
- 磁盘瓶颈
- 网络等待时间
建议采取的行动:
- 扩展存储性能。
- 审查书写关注设置。
- 如果持续滞后,则升级到更高的计划。
步骤 5:分片群集考虑因素(如适用)
以下情况可能需要分片:
- 工作集大于内存
- 即使经过扩展,单节点 IOPS 也已达到最大值
- 需要进行水平写入缩放
- 收藏超过 1-2 TB
如果您的部署使用了分片,请运行
sh.status()
检查
- 区块分布不均
- 巨型块
- 流量集中在一个碎片上
建议采取的行动:
- 审查分区密钥选择。
- 避免分片密钥单调递增。
- 考虑散列分块密钥。
分片密钥选择不当会严重影响大规模运行时的性能。
步骤 6:删除大量数据后
删除相当比例的数据并不会立即减少操作系统层面的磁盘使用量。
可能产生的影响
- 内部分裂
- 磁盘利用率高
- 性能降低
建议采取的行动:
- 仔细规划压实作业。
- 对于严重的碎片,可考虑转储和还原。
- 将磁盘利用率保持在 80-85% 以下。
合理安排维护活动。
第 7 步:检查锁定争用情况
锁竞争会严重影响并发操作和整体吞吐量。
-
检查全局锁统计:
db.serverStatus().locks -
检查当前操作是否锁定:
db.currentOp({ $or: [ { waitingForLock: true }, { "locks.Global": "w" } ] }) -
分析锁定等待时间:
db.serverStatus().globalLock
需要注意什么?
currentQueue价值较高(读者或作家)。waitingForLock: true的操作。- 持有锁的长期运行操作。
- 建立索引,阻止操作。
常见原因
- 没有适当索引的长时间查询。
- 大型写入操作。
- 索引建立在大型集合上。
- 管理命令(压缩、repairDatabase )。
建议采取的行动:
- 必要时,关闭长期运行的操作:
db.killOp(opid) - 在后台建立索引
db.collection.createIndex({ field: 1 }, { background: true }) - 将大型操作分成较小的批次。
- 将维护作业安排在交通流量较小的时段。
- 适当使用“读关注”和“写关注”。
步骤 8:分析工作量模式
了解您的工作量模式有助于确定优化机会。
-
检查运行计数器:
db.serverStatus().opcounters -
分析一段时间内的运行情况:
db.serverStatus().opcountersRepl -
确定热门藏品:
db.adminCommand({ top: 1 }) -
检查读取比率与写入比率的比较:
var stats = db.serverStatus().opcounters; print("Read ratio: " + (stats.query + stats.getmore) / (stats.query + stats.getmore + stats.insert + stats.update + stats.delete));
需要注意什么?
- 对特定藏品进行不相称的操作
- 读写比或写读比高
- 运行次数突然激增
- 基于时间的模式(高峰时段)
建议采取的行动:
- 首先优化经常访问的收藏集。
- 对于读取繁重的工作负载,可考虑使用读取副本。
- 使用适当的阅读首选项。
- 对频繁读取的数据实施缓存。
- 审查热门藏品的索引编制策略。
- 考虑对写入量大的集合进行分片。
步骤 9:调查内存压力和高速缓存效率
MongoDB's WiredTiger 存储引擎在很大程度上依赖于高速缓存的效率。
-
检查 WiredTiger 缓存统计数据:
db.serverStatus().wiredTiger.cache -
审查关键指标:
var cache = db.serverStatus().wiredTiger.cache; print("Cache size: " + cache["bytes currently in the cache"]); print("Max cache size: " + cache["maximum bytes configured"]); print("Pages read into cache: " + cache["pages read into cache"]); print("Pages written from cache: " + cache["pages written from cache"]); print("Cache hit ratio: " + (1 - cache["pages read into cache"] / (cache["pages read into cache"] + cache["pages requested from the cache"]))); -
检查驱逐压力:
db.serverStatus().wiredTiger.cache["pages evicted by application threads"]
需要注意什么?
- 缓存命中率低于 95
- 高驱逐率
- 缓存大小始终为最大值
- 执行驱逐的应用程序线程
估算工作装置尺寸:
db.serverStatus().wiredTiger.cache["tracked dirty bytes in the cache"]
建议采取的行动:
- 如果缓存一直满,则扩展到内存更大的计划。
- 审查并优化索引(删除不使用的索引)。
- 限制查询结果集的大小。
- 使用投影缩小文档尺寸。
- 考虑将旧数据归档。
- 监控工作机组尺寸趋势。
内存分配最佳实践
- WiredTiger 缓存应为可用 RAM 的 50%(默认值)。
- 为其他进程留出足够的内存。
- 监控交换机的使用情况,应尽量减少交换机的使用。
第 10 步查看写入关注和读取首选项设置
写入关注和读取偏好设置对性能和一致性有很大影响。
-
检查当前的写入问题:
db.getWriteConcern() -
检查副本集配置:
rs.conf() -
写出关注选项:
书写关注选项 写下关注 耐久性 性能 用例 w: 1低 高 非关键数据,高吞吐量 w: "majority"高 中 默认的平衡方法 w: <number>中-高 中低 具体副本数量 j: true最高 最低 需要日志同步的关键数据 -
阅读偏好选项:
阅读偏好选项 阅读偏好 一致性 性能 用例 primary最高 中 默认,一致性强 primaryPreferred高 中-高 回退到二级 secondary最终 高 分析、报告 secondaryPreferred最终 高 阅读缩放 nearest最终 最高 最低延迟 -
在申请表中勾选“读取偏好”:
// Example in Node.js driver db.collection('users').find({}).readPreference('secondary')
需要注意什么?
- 对非关键数据的写入要求过于严格
- 在最终一致性可以接受的情况下,使用
primary读取首选项 - 未利用辅助设备处理读取量大的工作负载
建议采取的行动:
- 将
w: 1用于高吞吐量的非关键写入。 - 重要数据使用
w: "majority"(默认)。 - 使用
secondary或secondaryPreferred进行分析查询。 - 考虑将
nearest用于地理分布广泛的应用程序。 - 兼顾一致性要求和性能需求。
- 测试负载下的不同配置。
步骤 11:监控备份和维护的影响
备份操作和维护任务会暂时影响性能。
IBM Cloud 备份计划
Databases for MongoDB 自动进行备份。 在 IBM Cloud 控制台的备份下查看备份计划。
检查正在进行的备份操作:
db.currentOp({
$or: [
{ op: "command", "command.backup": { $exists: true } },
{ desc: /^conn/ }
]
})
需要注意什么?
- 备份窗口期间性能下降
- 备份时磁盘 I/O 增加
- 备份过程中的复制滞后
建议采取的行动:
- 在备份期间监控性能指标。
- 如果备份一直影响性能,则考虑进行扩展。
- 审查备份保留政策。
- 计划在恢复操作期间增加资源使用量。
维护操作最佳做法
- 在低流量时段安排指数构建。
- 尽可能使用背景索引构建。
- 在维护期间监控复制滞后。
- 首先在非生产环境中测试维护操作。
- 与 IBM Cloud 维护窗口协调。