故障排除 Databases for MongoDB

本指南可帮助您识别和解决在 IBM Cloud 上运行并由 MongoDB 支持的 Databases for MongoDB 部署中的性能问题。

您还可以在下面找到有关解决性能问题的更多信息:

如果您的应用程序遇到响应缓慢、超时或数据库性能不一致的问题,请考虑以下步骤和信息。

性能问题的症状

您可能会观察到以下症状,这些症状表明性能出现了问题:

  • 应用程序延迟增加
  • 查询日志记录缓慢
  • CPU 或内存使用率高
  • 磁盘延迟增加
  • 复制延迟
  • 连接超时数

完成以下步骤以确定问题的原因:

步骤 1:检查资源利用情况

  1. 登录 IBM Cloud 控制台并导航至 MongoDB 部署。

  2. 审查监测部分,以了解

    • CPU 利用率
    • 内存使用率
    • 磁盘 IOPS 和延迟
    • 活动连接数

需要注意什么?

  • CPU 始终高于 75
  • 内存始终保持在 80% 以上
  • 磁盘延迟随着时间推移而增加
  • 接近计划限额的连接

建议采取的行动:

  • 如果磁盘延迟较高,则增加存储或 IOPS。
  • 查看应用程序中的工作量峰值。

如果资源使用量持续升高,建议进行扩展。

步骤 2:识别慢速查询

查询速度慢是导致性能下降的最常见原因之一。

  1. 启用剖析:

    db.setProfilingLevel(1, { slowms: 100 })
    
  2. 回顾最近的缓慢行动:

    db.system.profile.find().sort({ ts: -1 }).limit(20)
    
  3. 分析查询执行情况:

    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" (默认)。
  • 使用 secondarysecondaryPreferred 进行分析查询。
  • 考虑将 nearest 用于地理分布广泛的应用程序。
  • 兼顾一致性要求和性能需求。
  • 测试负载下的不同配置。

步骤 11:监控备份和维护的影响

备份操作和维护任务会暂时影响性能。

IBM Cloud 备份计划

Databases for MongoDB 自动进行备份。 在 IBM Cloud 控制台的备份下查看备份计划。

检查正在进行的备份操作:

db.currentOp({
  $or: [
    { op: "command", "command.backup": { $exists: true } },
    { desc: /^conn/ }
  ]
})

需要注意什么?

  • 备份窗口期间性能下降
  • 备份时磁盘 I/O 增加
  • 备份过程中的复制滞后

建议采取的行动:

  • 在备份期间监控性能指标。
  • 如果备份一直影响性能,则考虑进行扩展。
  • 审查备份保留政策。
  • 计划在恢复操作期间增加资源使用量。

维护操作最佳做法

  • 在低流量时段安排指数构建。
  • 尽可能使用背景索引构建。
  • 在维护期间监控复制滞后。
  • 首先在非生产环境中测试维护操作。
  • 与 IBM Cloud 维护窗口协调。