Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

MongoDB 最佳实践

MongoDB 最佳实践(生产级运维 + 开发 + 性能优化)完整指南,直接可用于架构设计、开发规范、数据库规划与调优。

内容:

  1. 架构设计最佳实践
  2. 数据模型 & Schema 设计
  3. 索引设计
  4. 性能优化
  5. 运维 & 部署最佳实践
  6. 安全最佳实践
  7. 监控最佳实践
  8. 开发编码最佳实践
  9. 常见反模式(千万不要做)

🔥 一、架构设计最佳实践

1. 优先使用复制集(Replica Set)

至少:

primary + secondary + arbiter(或第二个 secondary)

目的:

  • 高可用
  • 自动选举
  • 自动故障切换

💡 不要单节点部署生产环境!

2. 数据量大时使用分片(Sharding)

适用于:

  • 单 collection > 500GB
  • 单节点写入压力很大
  • 需要水平扩容

分片键原则:

  • 分散写入
  • 不要单调递增(_id 自动生成的 ObjectId 很单调)

推荐分片键:

  • hashed(_id)
  • hashed(user_id)

3. 使用 WiredTiger 引擎

MongoDB 默认使用 WiredTiger,支持:

  • 压缩
  • 文档级锁
  • 更高性能

不要再使用 MMAPv1(已废弃)。

🔥 二、数据模型最佳实践

1. 文档大小控制 < 16MB

超过会报错:

BSONObj size: xxx is invalid

推荐最大 1~2MB。

2. 嵌套文档(Embed) vs 引用(Reference)

✅ 什么时候用嵌套(Embed)

适合:

  • 数据一对一或一对少
  • 数据经常一起读取
  • 例如订单 -> 商品列表

✅ 什么时候用引用(Reference)

适合:

  • 一对多(非常多)
  • 大量更新
  • 不经常一起读取

3. 字段命名不要使用大写

推荐:

snake_case(推荐)
camelCase(也可以)

⚠️ 不要使用中文字段名。

4. 避免深度嵌套文档

深度 > 5 层 会导致查询性能变差。

🔥 三、索引最佳实践

1. 必须创建索引的情况

  • where 查询字段
  • sort 排序字段
  • join 字段($lookup)
  • 唯一字段(unique)

2. 索引要“左前缀”使用

如复合索引:

{ a: 1, b: 1, c: 1 }

有效索引字段是:

a
a, b
a, b, c

不能直接用 b, c。

3. 避免过多索引

每个 index 都会:

  • 占用内存
  • 降低写入性能

4. 定期检查 COLLSCAN(全表扫描)

db.collection.find({...}).explain("executionStats")

出现 COLLSCAN 必须加索引。

🔥 四、性能最佳实践

1. 永远不要在查询中使用正则前缀模糊

❌ 错误:

db.users.find({ name: /abc/ })

✅ 正确:

db.users.find({ name: /^abc/ })

2. 避免大 $in 查询

❌:

id in [1,2,3,4...50000]

会导致 huge COLLSCAN。

3. 分页使用 _id + limit(更快)

比 skip 快数十倍。

4. 聚合大量数据时使用 allowDiskUse

db.collection.aggregate([...], { allowDiskUse: true })

5. 使用投影减少返回字段

只要需要字段:

{ name: 1, age: 1 }

🔥 五、运维 & 部署最佳实践

1. RAID10 + SSD 是标配

理由:

  • WiredTiger 需要大量随机 I/O
  • SSD 显著提升写入性能

2. 禁止 swap(性能灾难)

设置:

vm.swappiness = 1

3. Oplog 保持至少 24 小时

查看:

rs.printReplicationInfo()

4. 数百万级 collection 应分库分集合

避免:

  • 太多小集合
  • 每个都有索引 -> 内存爆炸

🔥 六、安全最佳实践

1. 开启认证

security:
  authorization: enabled

2. 不要使用 admin 库作为业务库

避免用户权限过高。

3. 使用角色权限

创建最小权限用户:

db.createUser({
  user: "app",
  pwd: "xxx",
  roles: [{ role: "readWrite", db: "mydb" }]
})

4. 使用 TLS/SSL

开启证书加密传输。

🔥 七、监控最佳实践

必监控指标:

WiredTiger:

  • cache usage
  • eviction
  • dirty bytes

Replication:

  • replication lag(必须 < 10 秒)
  • oplog time window

Performance:

  • opcounters
  • slow queries
  • queue length
  • I/O 读写

推荐使用:

  • Prometheus + Grafana
  • Percona Monitoring (PMM)

🔥 八、开发编码最佳实践

1. 不要在代码中创建太多连接

✅ 使用连接池(pool)

2. 写操作要 idempotent(幂等)

例如:

updateOne(upsert=True)

3. 避免单文档大字段更新

会触发:

  • document move
  • rewrite entire doc

成本高!

4. 使用 bulkWrite 批量写入

批量性能比循环 insert 快 10x+。

🔥 九、常见反模式(千万不要做)

  • ❌ 大量使用 $where(JS 执行,极慢)
  • ❌ 使用 skip 进行深度分页(性能噩梦)
  • ❌ 在字段上使用正则前置通配符 .*abc
  • ❌ 文档无限深度嵌套
  • ❌ 同一集合创建几十个索引
  • ❌ 垃圾分片键导致热点问题
  • ❌ 多字段常改 -> 嵌套太深造成整文档重写