Skip to content

MongoDB IO 参数调优

存储引擎 IO 参数

WiredTiger 缓存配置

参数名storage.wiredTiger.engineConfig.cacheSizeGB

功能:指定 WiredTiger 存储引擎使用的缓存大小(GB)

默认值:系统内存的 50%

调优建议

  • 对于专用 MongoDB 服务器,建议设置为系统内存的 60-70%
  • 对于共享服务器,建议根据其他进程的内存需求调整
  • 避免设置过大,导致系统内存不足

配置示例

yaml
storage:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 16

WiredTiger 并发控制

参数名storage.wiredTiger.engineConfig.concurrentReadTransactions

功能:指定 WiredTiger 允许的并发读事务数

默认值:128

调优建议

  • 根据系统 CPU 核心数调整
  • 对于读密集型应用,可以适当增加
  • 避免设置过大,导致资源竞争

相关参数

  • concurrentWriteTransactions:并发写事务数,默认 128

配置示例

yaml
storage:
  wiredTiger:
    engineConfig:
      concurrentReadTransactions: 256
      concurrentWriteTransactions: 128

WiredTiger 预读配置

参数名storage.wiredTiger.engineConfig.readahead

功能:指定 WiredTiger 的预读大小(KB)

默认值:0(自动)

调优建议

  • 对于顺序访问模式,建议设置为 128-256 KB
  • 对于随机访问模式,建议设置为较小值或保持默认
  • 避免设置过大,导致内存浪费

配置示例

yaml
storage:
  wiredTiger:
    engineConfig:
      readahead: 256

WiredTiger 检查点配置

参数名storage.wiredTiger.engineConfig.checkpointIntervalSecs

功能:指定 WiredTiger 检查点的间隔时间(秒)

默认值:60 秒

调优建议

  • 对于写密集型应用,可以适当缩短间隔
  • 对于读密集型应用,可以适当延长间隔
  • 避免设置过短,导致频繁的检查点操作影响性能

配置示例

yaml
storage:
  wiredTiger:
    engineConfig:
      checkpointIntervalSecs: 30

磁盘 IO 参数

日志同步策略

参数名storage.journal.commitIntervalMs

功能:指定日志提交的间隔时间(毫秒)

默认值:100 毫秒

调优建议

  • 对于需要高可靠性的应用,建议设置为较小值(如 50 毫秒)
  • 对于性能要求较高的应用,可以适当延长(如 200-500 毫秒)
  • 避免设置过大,导致数据丢失风险增加

配置示例

yaml
storage:
  journal:
    commitIntervalMs: 200

日志文件大小

参数名storage.journal.sizeMB

功能:指定单个日志文件的大小(MB)

默认值:100 MB

调优建议

  • 对于写密集型应用,可以适当增加日志文件大小
  • 避免设置过大,导致日志恢复时间过长

配置示例

yaml
storage:
  journal:
    sizeMB: 200

数据文件分配策略

参数名storage.mmapv1.smallFiles

功能:指定是否使用小文件分配策略(仅适用于 MMAPv1 存储引擎)

默认值:false

调优建议

  • 对于 MMAPv1 存储引擎,小文件策略适合磁盘空间有限的环境
  • WiredTiger 存储引擎不使用此参数

配置示例

yaml
storage:
  mmapv1:
    smallFiles: true

网络 IO 参数

连接池配置

参数名net.maxIncomingConnections

功能:指定 MongoDB 允许的最大并发连接数

默认值:65536

调优建议

  • 根据服务器资源和业务需求调整
  • 建议设置为服务器可用连接数的 80%
  • 避免设置过大,导致资源耗尽

配置示例

yaml
net:
  maxIncomingConnections: 10000

TCP 连接参数

参数名net.socketTimeoutMS

功能:指定 TCP 连接的超时时间(毫秒)

默认值:0(无超时)

调优建议

  • 建议设置为 30000-60000 毫秒(30-60 秒)
  • 避免设置过小,导致正常连接被断开
  • 避免设置过大,导致无效连接长时间占用资源

相关参数

  • connectTimeoutMS:连接超时时间,默认 10000 毫秒
  • keepAlive:是否启用 TCP keepalive,默认 true
  • keepAliveInitialDelay:TCP keepalive 初始延迟,默认 300 秒

配置示例

yaml
net:
  socketTimeoutMS: 30000
  connectTimeoutMS: 10000
  keepAlive: true
  keepAliveInitialDelay: 300

网络压缩

参数名net.compression.compressors

功能:指定允许的网络压缩算法

默认值snappy

可选值

  • snappy:默认,压缩速度快,压缩比适中
  • zlib:压缩比高,压缩速度慢
  • zstd:压缩比和速度都很好(MongoDB 4.2+)

调优建议

  • 对于高带宽网络,可以禁用压缩
  • 对于低带宽网络,建议使用 snappyzstd
  • 避免在 CPU 资源紧张的环境中使用高压缩比算法

配置示例

yaml
net:
  compression:
    compressors: snappy,zstd

查询 IO 优化

游标超时设置

参数名setParameter.cursorTimeoutMillis

功能:指定游标的超时时间(毫秒)

默认值:300000 毫秒(5 分钟)

调优建议

  • 对于长时间运行的查询,可以适当延长超时时间
  • 对于短期查询,建议保持默认或缩短
  • 避免设置过大,导致资源长时间被占用

配置示例

yaml
setParameter:
  cursorTimeoutMillis: 600000

批处理大小

参数名net.maxBsonObjectSize

功能:指定单个 BSON 对象的最大大小(字节)

默认值:16777216(16 MB)

调优建议

  • 对于大型文档,可以适当增加
  • 避免设置过大,导致网络传输和内存压力

相关参数

  • net.maxMessageSizeBytes:单个消息的最大大小,默认 48 MB

配置示例

yaml
net:
  maxBsonObjectSize: 33554432
  maxMessageSizeBytes: 96000000

复制集 IO 优化

Oplog 大小配置

参数名replication.oplogSizeMB

功能:指定 Oplog 的大小(MB)

默认值

  • 对于 64 位系统,默认 5% 的可用磁盘空间,最小值 1 GB
  • 对于 32 位系统,默认 192 MB

调优建议

  • 根据数据写入速率调整 Oplog 大小
  • 建议 Oplog 窗口大小至少为 24 小时
  • 对于写密集型应用,建议增加 Oplog 大小

配置示例

yaml
replication:
  oplogSizeMB: 10240

复制线程配置

参数名replication.secondaryIndexPrefetch

功能:指定副本节点在复制过程中预取索引的策略

可选值

  • all:预取所有索引(默认)
  • none:不预取索引
  • _id_only:仅预取 _id 索引

调优建议

  • 对于 IO 密集型环境,建议设置为 none_id_only
  • 对于 CPU 密集型环境,可以保持默认

配置示例

yaml
replication:
  secondaryIndexPrefetch: none

分片集群 IO 优化

平衡器配置

参数名sharding.balancer.window

功能:指定平衡器的运行窗口

默认值:无限制(24/7 运行)

调优建议

  • 对于生产环境,建议将平衡器运行时间限制在低峰期
  • 避免在业务高峰期运行平衡器,影响性能

配置示例

yaml
sharding:
  balancer:
    window:
      start: "22:00"
      stop: "06:00"

块大小配置

参数名sharding.chunkSize

功能:指定分片集群中块的大小(MB)

默认值:64 MB

调优建议

  • 对于大型文档或写密集型应用,可以适当增加块大小(128-256 MB)
  • 对于小型文档或读密集型应用,可以保持默认或减小
  • 避免设置过大,导致迁移时间过长

配置示例

yaml
sharding:
  chunkSize: 128

IO 调优最佳实践

1. 硬件优化

磁盘选择

  • 优先使用 SSD 或 NVMe 磁盘,提供更高的 IOPS 和更低的延迟
  • 对于日志文件,建议使用高速磁盘
  • 考虑使用 RAID 配置,提高可靠性和性能

网络优化

  • 使用千兆或万兆以太网
  • 对于跨区域部署,使用专用网络连接
  • 配置适当的网络 QoS

2. 存储引擎选择

存储引擎比较

  • WiredTiger:默认存储引擎,支持压缩、加密和并发控制,适合大多数场景
  • In-Memory:适合高性能、低延迟需求,数据完全存储在内存中
  • MMAPv1:旧版存储引擎,不建议使用

选择建议

  • 大多数场景推荐使用 WiredTiger
  • 对于内存足够且对延迟要求极高的场景,考虑使用 In-Memory 存储引擎

3. 数据模型优化

文档设计

  • 避免过大的文档(建议不超过 16 MB)
  • 合理使用嵌入式文档和引用
  • 考虑数据访问模式,优化文档结构

索引优化

  • 为频繁查询的字段创建索引
  • 避免创建过多索引
  • 优化复合索引顺序

4. 查询优化

查询模式优化

  • 避免全表扫描
  • 使用覆盖索引
  • 限制返回字段
  • 合理使用分页

聚合查询优化

  • 优化聚合管道顺序
  • 使用 allowDiskUse 处理大型聚合
  • 考虑使用 $out$merge 存储聚合结果

5. 监控与分析

IO 监控指标

  • 磁盘使用率
  • IOPS(每秒输入输出操作数)
  • 吞吐量(MB/s)
  • 延迟(ms)
  • 队列长度

监控工具

  • iostat:系统级 IO 监控
  • mongostat:MongoDB 级 IO 监控
  • db.serverStatus().wiredTiger.cache:WiredTiger 缓存监控
  • MongoDB Atlas/Ops Manager:集成监控

6. 负载均衡

读写分离

  • 使用副本集进行读写分离
  • 将读请求分发到副本节点
  • 主节点仅处理写请求和关键读请求

分片集群

  • 使用分片集群分散读写负载
  • 选择合适的分片键
  • 监控分片平衡状态

常见问题(FAQ)

Q1: 如何判断 MongoDB 是否存在 IO 瓶颈?

A1: 可以通过以下指标判断:

  • 高磁盘 I/O 使用率(> 80%)
  • 高 IO 等待时间(> 50ms)
  • 队列长度持续增长
  • 高 CPU iowait 百分比(> 20%)
  • 慢查询数量增加
  • 复制延迟增加

Q2: WiredTiger 缓存大小设置多少合适?

A2: 对于专用 MongoDB 服务器,建议设置为系统内存的 60-70%。例如,对于 32GB 内存的服务器,建议设置为 19-22GB。对于共享服务器,需要根据其他进程的内存需求调整。

Q3: 如何优化 MongoDB 的写入性能?

A3: 优化写入性能的方法:

  • 调整 WiredTiger 缓存大小
  • 优化日志提交间隔
  • 使用适当的写入关注点
  • 考虑批量写入
  • 使用 SSD 磁盘
  • 优化索引设计

Q4: 网络压缩会影响性能吗?

A4: 网络压缩会增加 CPU 开销,但可以减少网络带宽使用。对于低带宽网络,压缩可以提高性能;对于高带宽网络,可能会降低性能。建议根据实际环境测试后决定是否启用。

Q5: 如何监控 MongoDB 的 IO 性能?

A5: 可以使用以下工具监控:

  • iostat -x 1:查看系统级 IO 性能
  • mongostat --discover:查看 MongoDB 级 IO 性能
  • db.serverStatus().wiredTiger:查看 WiredTiger 存储引擎 IO 统计
  • MongoDB Atlas/Ops Manager:提供可视化的 IO 监控图表

Q6: 分片集群的块大小如何选择?

A6: 分片集群的块大小默认是 64MB。对于写密集型应用或大型文档,可以适当增加到 128MB 或 256MB;对于读密集型应用或小型文档,可以保持默认或减小。块大小影响数据迁移的频率和时间,需要根据实际场景调整。