Skip to content

MongoDB 资源限制配置

内存资源限制

WiredTiger 缓存限制

  1. 默认缓存大小

    • 默认使用系统内存的50%
    • 最低256MB
    • 最高10TB
  2. 配置方法

    yaml
    # mongod.conf
    storage:
      wiredTiger:
        engineConfig:
          cacheSizeGB: 8  # 设置为8GB
  3. 动态调整

    javascript
    // 动态调整缓存大小
    db.adminCommand({
      setParameter: 1,
      wiredTigerEngineRuntimeConfig: "cache_size=8G"
    })
  4. 监控缓存使用

    javascript
    // 查看缓存使用情况
    db.serverStatus().wiredTiger.cache

操作系统内存限制

  1. Linux cgroups 限制

    bash
    # 创建cgroup
    sudo cgcreate -g memory:mongodb
    
    # 设置内存限制为16GB
    sudo cgset -r memory.limit_in_bytes=17179869184 mongodb
    
    # 运行MongoDB在cgroup中
    sudo cgexec -g memory:mongodb mongod --config /etc/mongod.conf
  2. Docker 内存限制

    bash
    # 运行MongoDB容器,限制内存为16GB
    docker run -d \
      --name mongodb \
      --memory 16g \
      --memory-swap 16g \
      -p 27017:27017 \
      mongo --wiredTigerCacheSizeGB 8

连接数限制

MongoDB 连接限制

  1. 默认连接数

    • 默认最大连接数为100000
    • 可通过maxConns参数调整
  2. 配置方法

    yaml
    # mongod.conf
    net:
      maxIncomingConnections: 50000  # 设置为50000
  3. 动态调整

    javascript
    // 动态调整最大连接数
    db.adminCommand({
      setParameter: 1,
      maxConns: 50000
    })
  4. 监控连接数

    javascript
    // 查看当前连接数
    db.serverStatus().connections

应用连接池配置

  1. Node.js 驱动连接池

    javascript
    const { MongoClient } = require('mongodb');
    
    const uri = 'mongodb://localhost:27017';
    const client = new MongoClient(uri, {
      maxPoolSize: 100,  // 最大连接数
      minPoolSize: 10,   // 最小连接数
      maxIdleTimeMS: 30000,  // 连接最大空闲时间
      connectTimeoutMS: 10000,  // 连接超时时间
      socketTimeoutMS: 45000  // Socket超时时间
    });
  2. Java 驱动连接池

    java
    MongoClientSettings settings = MongoClientSettings.builder()
        .applyToConnectionPoolSettings(builder -> {
            builder.maxSize(100);  // 最大连接数
            builder.minSize(10);   // 最小连接数
            builder.maxWaitTime(30, TimeUnit.SECONDS);  // 最大等待时间
        })
        .build();

CPU 资源限制

CPU 亲和性设置

  1. Linux taskset 命令

    bash
    # 限制MongoDB使用CPU 0和1
    taskset -c 0,1 mongod --config /etc/mongod.conf
  2. cgroups CPU 限制

    bash
    # 创建cgroup
    sudo cgcreate -g cpu:mongodb
    
    # 限制使用2个CPU核心
    sudo cgset -r cpu.cfs_quota_us=200000 mongodb
    sudo cgset -r cpu.cfs_period_us=100000 mongodb
    
    # 运行MongoDB在cgroup中
    sudo cgexec -g cpu:mongodb mongod --config /etc/mongod.conf
  3. Docker CPU 限制

    bash
    # 运行MongoDB容器,限制使用2个CPU核心
    docker run -d \
      --name mongodb \
      --cpus 2 \
      -p 27017:27017 \
      mongo

CPU 使用率监控

  1. 使用 mongostat 监控

    bash
    # 监控CPU使用率
    mongostat --cpu
  2. 使用 serverStatus 监控

    javascript
    // 查看CPU使用率
    db.serverStatus().processCpuTotal

磁盘资源限制

磁盘空间监控

  1. 配置磁盘空间告警

    yaml
    # mongod.conf
    storage:
      mmapv1:
        quota:
          enforced: true
          maxFilesPerDB: 8
  2. 监控磁盘使用

    javascript
    // 查看数据库大小
    db.stats()
    
    // 查看集合大小
    db.collection.stats()
  3. 使用 db.adminCommand 监控

    javascript
    // 查看所有数据库大小
    db.adminCommand({ listDatabases: 1, nameOnly: false })

磁盘 I/O 限制

  1. Linux cgroups I/O 限制

    bash
    # 创建cgroup
    sudo cgcreate -g blkio:mongodb
    
    # 限制写入速度为100MB/s
    sudo cgset -r blkio.throttle.write_bps_device="8:0 104857600" mongodb
    
    # 运行MongoDB在cgroup中
    sudo cgexec -g blkio:mongodb mongod --config /etc/mongod.conf
  2. 监控磁盘 I/O

    javascript
    // 查看磁盘I/O状态
    db.serverStatus().diskIO

网络资源限制

端口与绑定限制

  1. 绑定IP配置

    yaml
    # mongod.conf
    net:
      bindIp: 127.0.0.1,192.168.1.100  # 绑定到指定IP
      port: 27017  # 指定端口
  2. IPv6 配置

    yaml
    # mongod.conf
    net:
      ipv6: true
      bindIpAll: true

连接速率限制

  1. 使用 iptables 限制连接速率

    bash
    # 限制来自同一IP的连接速率为每秒10个
    sudo iptables -A INPUT -p tcp --dport 27017 -m state --state NEW -m limit --limit 10/s --limit-burst 20 -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport 27017 -m state --state NEW -j DROP
  2. MongoDB 连接限制参数

    javascript
    // 启用连接速率限制
    db.adminCommand({
      setParameter: 1,
      maxIncomingConnectionsPerSource: 1000
    })

集合与文档限制

文档大小限制

  1. 默认限制

    • 单个文档最大16MB
    • 超过限制的文档需要使用GridFS存储
  2. 检查文档大小

    javascript
    // 检查集合中文档大小
    db.collection.aggregate([
      { $project: { size: { $bsonSize: "$$ROOT" } } },
      { $sort: { size: -1 } },
      { $limit: 10 }
    ])
  3. 使用 GridFS 存储大文件

    bash
    # 使用mongofiles上传大文件
    mongofiles --host localhost:27017 --db test put large-file.zip

集合大小限制

  1. 理论限制

    • 单个集合大小无硬性限制
    • 受限于磁盘空间
    • 建议单个集合不超过1TB
  2. 分片集合

    • 超过限制时建议使用分片集群
    • 自动将数据分布到多个分片

索引限制

索引大小限制

  1. B树索引

    • 单个索引键大小限制为1024字节
    • 超过限制的键不会被索引
  2. 复合索引

    • 最大32个字段
    • 总索引键大小建议不超过4096字节
  3. 检查索引大小

    javascript
    // 查看索引大小
    db.collection.stats().indexSizes

索引数量限制

  1. 每个集合的索引数量

    • 建议不超过64个
    • 过多索引会影响写入性能
  2. 监控索引使用

    javascript
    // 查看索引使用情况
    db.serverStatus().indexCounters

操作时间限制

慢查询阈值

  1. 默认设置

    • 默认100毫秒
    • 超过该时间的查询会被记录到慢查询日志
  2. 配置方法

    yaml
    # mongod.conf
    operationProfiling:
      slowOpThresholdMs: 500  # 设置为500毫秒
      mode: slowOp  # 仅记录慢查询
  3. 动态调整

    javascript
    // 动态调整慢查询阈值
    db.adminCommand({
      setParameter: 1,
      slowMS: 500
    })

操作超时设置

  1. 客户端超时

    javascript
    // 设置查询超时为5秒
    db.collection.find().maxTimeMS(5000)
  2. 全局操作超时

    javascript
    // 设置全局操作超时
    db.adminCommand({
      setParameter: 1,
      maxTimeMS: 30000
    })

资源限制监控

MongoDB 内置监控

  1. 使用 db.serverStatus()

    javascript
    // 查看服务器状态
    db.serverStatus()
  2. 使用 db.stats()

    javascript
    // 查看数据库状态
    db.stats()
  3. 使用 db.currentOp()

    javascript
    // 查看当前操作
    db.currentOp()

第三方监控工具

  1. MongoDB Atlas

    • 云端MongoDB监控
    • 提供资源使用面板
    • 支持自定义告警
  2. Prometheus + Grafana

    • 开源监控组合
    • 使用MongoDB Exporter获取指标
    • 可自定义监控面板
  3. Datadog

    • 商业监控工具
    • 提供MongoDB专用监控集成
    • 支持自动告警

常见问题(FAQ)

Q1: 如何确定合适的WiredTiger缓存大小?

A1: 确定WiredTiger缓存大小的建议:

  • 对于专用MongoDB服务器,设置为系统内存的50-60%
  • 为操作系统和其他进程预留足够内存(至少2GB)
  • 监控缓存使用率,避免持续超过90%
  • 对于分片集群,考虑每个分片的内存需求

Q2: 如何处理连接数过多的问题?

A2: 处理连接数过多的方法:

  • 调整应用的连接池大小
  • 增加MongoDB实例或使用分片集群
  • 优化应用代码,减少连接创建
  • 使用连接复用技术

Q3: 如何限制MongoDB的CPU使用率?

A3: 限制MongoDB CPU使用率的方法:

  • 使用Linux cgroups
  • 使用Docker CPU限制
  • 使用taskset设置CPU亲和性
  • 优化查询,减少CPU密集型操作

Q4: 文档大小超过16MB怎么办?

A4: 处理超过16MB文档的方法:

  • 使用GridFS存储大文件
  • 将大文档拆分为多个相关文档
  • 存储外部引用,将实际数据存储在文件系统

Q5: 如何监控MongoDB的资源使用?

A5: 监控MongoDB资源使用的方法:

  • 使用MongoDB内置命令(serverStatus, stats)
  • 使用mongostat和mongotop命令行工具
  • 使用第三方监控工具(Prometheus + Grafana, Datadog)
  • 设置资源使用告警

Q6: 过多索引会有什么影响?

A6: 过多索引的影响:

  • 增加写入操作的开销
  • 占用更多磁盘空间
  • 增加内存使用
  • 降低索引使用效率
  • 建议定期清理不使用的索引