一、 MongoDB 核心概念解析
📄 文档与集合
MongoDB是文档型数据库,数据以BSON(Binary JSON)格式存储。与关系型数据库不同,MongoDB的集合(Collection)没有固定的表结构,允许同一集合中的文档拥有不同的字段。
🔍 索引机制
索引是提升查询性能的关键。MongoDB支持单字段索引、复合索引、多键索引、地理空间索引和文本索引。默认情况下,_id字段会自动创建唯一索引。
⚡ 面试题考点: 复合索引的顺序如何影响查询性能?
⚙️ 聚合框架
聚合管道(Aggregation Pipeline)是MongoDB强大的数据处理工具,支持分组、过滤、排序、投影等操作。它类似于Unix管道,数据经过多个阶段处理后输出结果。
二、 MongoDB 高频面试题详解
以下整理了面试官最常问的5个核心问题,涵盖原理、应用及实战场景。
Q1: 在什么情况下MongoDB索引会失效?
深度解析: 虽然MongoDB索引效率很高,但在某些查询模式下索引可能不被使用或效率低下。
- 前缀匹配缺失: 对于复合索引 (A, B, C),如果查询条件只包含 B 或 C,而不包含 A,则索引可能无法有效利用(除非使用覆盖索引或特定优化)。
- 正则表达式: 以 ^ 开头的正则表达式可以使用索引,但其他形式的正则表达式通常会导致全表扫描。
- 类型不匹配: 查询值的类型与索引字段类型不一致时,索引可能失效。例如,用字符串 "123" 查询数字类型的字段。
- 隐式类型转换: 在查询中使用运算或函数处理字段值时,如
db.col.find({ age: { $gt: 18 } })中若对 age 进行计算,索引可能失效。
Q2: 聚合框架和 MapReduce 有什么区别?
深度解析: 随着MongoDB 4.2版本的发布,MapReduce已逐渐被废弃,聚合框架成为首选。
| 特性 | 聚合框架 (Aggregation) | MapReduce |
|---|---|---|
| 性能 | 高性能,C++实现,管道优化 | 较慢,JavaScript引擎执行 |
| 易用性 | 声明式,链式调用,易于理解 | 命令式,需编写JS函数 |
| 功能 | 覆盖80%常见场景 | 理论上支持所有逻辑 |
| 状态 | 推荐,活跃维护 | 已废弃 (Deprecated) |
Q3: MongoDB 支持事务吗?
深度解析: MongoDB 3.6 版本开始支持多文档事务,但仅适用于副本集(Replica Sets)和分片集群(Sharded Clusters)。
事务特性遵循 ACID 原则,但需注意:
- 事务只能在会话(Session)中开启。
- 事务中只能操作同一个数据库中的集合。
- 长事务会影响性能,建议保持事务简短。
- 需要设置
w: "majority"以确保数据持久性。
Q4: 什么是分片(Sharding)?如何选择分片键?
深度解析: 分片是将数据分布到多个机器上的过程,用于支持大数据集的部署和高吞吐操作。
分片键选择原则:
- 高基数(High Cardinality): 分片键的值应尽可能分散,避免数据倾斜。
- 查询模式: 分片键应包含在大多数查询中,以减少跨节点查询(Scatter-Gather)。
- 单调递增 vs 随机: 单调递增键(如时间戳)可能导致热点写入;随机键(如Hash)可均匀分布但可能增加查询开销。
Q5: 如何进行数据迁移?
深度解析: 数据迁移是运维中的常见任务,MongoDB提供了多种工具:
- MongoDB Compass: 图形化工具,适合小数据量导入导出。
- mongoimport/mongoexport: 命令行工具,支持CSV、JSON、BSON格式。
- MongoDB Atlas Data Federation: 云原生方案,适合跨云迁移。
- Change Streams: 用于实时数据同步,实现零停机迁移。
三、 MongoDB 进阶架构设计
副本集提供高可用性(HA)。至少包含一个主节点(Primary)和两个从节点(Secondary)。主节点处理写操作,从节点同步数据并处理读操作。故障自动切换(Failover)是核心特性。
当数据量超过单机存储或吞吐量瓶颈时,引入分片。集群由三部分组成:
- Config Server: 存储集群元数据。
- Mongos: 路由服务器,客户端连接入口。
- Shard: 实际存储数据的副本集。
MongoDB 4.0+ 支持跨分片事务。使用两阶段提交(2PC)协议保证一致性。开发者需权衡一致性与性能,适当放宽一致性要求(如最终一致性)可提升系统吞吐量。
四、 MongoDB 性能优化实战
📈 查询优化
使用 explain() 分析查询计划。重点关注 IXSCAN(索引扫描)和 COLSCAN(集合扫描)。避免全表扫描,确保查询条件命中索引。
💾 存储优化
启用压缩(Compression)减少磁盘占用。使用预分配文件(Pre-allocating Files)避免频繁磁盘扩展。定期运行 reIndex 重建碎片化索引。
🚀 内存管理
MongoDB 使用 WiredTiger 存储引擎,支持页缓存。确保 cacheSizeGB 设置合理,通常建议为物理内存的 50%-70%。监控 page faults 指标,过高说明缓存不足。