外观
MongoDB 物理架构
WiredTiger 存储引擎
WiredTiger 核心特性
文档级并发控制
- 支持多个并发写操作
- 减少锁竞争
- 提高系统吞吐量
数据压缩
- 支持Snappy、Zlib和Zstd压缩算法
- 减少磁盘空间占用
- 降低I/O操作
加密支持
- 静态数据加密
- 传输数据加密
- 符合安全合规要求
检查点机制
- 定期创建一致性检查点
- 支持快速恢复
- 减少数据丢失风险
WiredTiger 数据结构
1. B树索引
WiredTiger使用B树作为主要的索引结构:
2. LSM树(可选)
WiredTiger也支持LSM树(日志结构合并树),适用于写入密集型场景。
WiredTiger 缓存机制
WiredTiger使用两级缓存机制:
WiredTiger缓存
- 存储热点数据
- 大小由
storage.wiredTiger.engineConfig.cacheSizeGB参数控制 - 默认使用系统内存的50%
操作系统页缓存
- 由操作系统管理
- 存储频繁访问的数据页
- 补充WiredTiger缓存
数据文件结构
MongoDB 数据文件组织
MongoDB的数据文件存储在指定的数据目录中,默认路径为/data/db(Linux/macOS)或C:\data\db(Windows)。
主要数据文件类型
1. 数据文件(.wt)
WiredTiger使用.wt扩展名存储数据:
collection-*.wt:存储集合数据index-*.wt:存储索引数据WiredTiger.wt:存储元数据WiredTiger.turtle:存储最新检查点信息
2. 日志文件(WiredTigerLog)
- 存储Write Ahead Log(WAL)
- 确保数据持久性
- 支持崩溃恢复
- 文件大小默认为128MB
- 自动轮转和清理
3. 临时文件(_tmp)
- 存储临时数据
- 如索引构建过程中的临时数据
- 操作完成后自动删除
4. 配置文件
mongod.conf:MongoDB配置文件WiredTigerLAS.wt:WiredTiger配置文件
数据文件命名规则
# 集合数据文件
table:collection-<namespace_hash>-<timestamp>.wt
# 索引数据文件
table:index-<namespace_hash>-<index_id>-<timestamp>.wt其中:
namespace_hash:集合命名空间的哈希值index_id:索引标识符timestamp:文件创建时间戳
索引的物理存储
索引文件结构
索引数据存储在独立的.wt文件中,每个索引对应一个文件。
索引类型的物理实现
1. 单字段索引
- 基于B树实现
- 存储字段值和文档ID的映射
- 支持高效的等值查询和范围查询
2. 复合索引
- 基于B树实现
- 存储多个字段的组合值
- 索引顺序影响查询性能
- 支持前缀查询
3. 多键索引
- 用于数组字段
- 为数组中的每个元素创建索引条目
- 自动检测数组字段并创建多键索引
4. 地理空间索引
- 基于GeoJSON格式
- 支持2D和2Dsphere索引
- 用于位置查询
5. 文本索引
- 用于文本搜索
- 支持分词、 stemming和停用词
- 基于倒排索引实现
6. 哈希索引
- 基于哈希函数
- 仅支持等值查询
- 不支持范围查询
索引存储优化
索引压缩
- WiredTiger支持索引压缩
- 减少索引占用空间
- 提高索引访问效率
索引前缀截断
- 对于长字符串,仅存储前缀
- 减少索引大小
- 提高查询效率
覆盖索引
- 索引包含查询所需的所有字段
- 避免回表查询
- 提高查询性能
数据持久化机制
Write Ahead Log (WAL)
WiredTiger使用Write Ahead Log确保数据持久性:
- 写操作首先写入WAL日志
- 然后写入内存缓存
- 定期将内存中的数据刷新到磁盘
检查点机制
检查点是数据库的一致性快照:
- 定期创建(默认每60秒或每2GB日志)
- 记录所有已提交的事务
- 用于崩溃恢复
- 提高恢复速度
数据刷新策略
- 定期刷新:默认每60秒
- 日志大小触发:当日志达到一定大小
- 手动触发:使用
fsync命令 - 事务提交:对于同步写关注
内存管理
MongoDB 内存结构
MongoDB的内存使用可以分为以下几个部分:
- WiredTiger缓存:存储热点数据和索引
- 操作系统页缓存:缓存磁盘数据页
- 连接内存:每个连接使用的内存
- 操作内存:执行操作所需的内存
- 聚合管道内存:聚合操作使用的内存
内存配置参数
yaml
# WiredTiger缓存大小
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 4
# 连接数限制
net:
maxIncomingConnections: 65536
# 操作内存限制
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100内存优化建议
- 合理设置缓存大小:根据系统内存调整
- 监控内存使用:使用
db.serverStatus().mem查看 - 优化查询:减少内存密集型操作
- 使用索引:减少全表扫描
- 限制连接数:避免过多连接占用内存
磁盘I/O优化
I/O 模式
MongoDB的I/O模式主要包括:
- 顺序写:WAL日志的写入
- 随机读:数据检索
- 顺序读:全表扫描或范围查询
I/O 优化策略
- 使用高速存储设备:SSD优于HDD
- 合理配置RAID:RAID 10适合MongoDB
- 分离日志和数据文件:减少I/O竞争
- 启用数据压缩:减少I/O操作
- 优化索引:减少随机I/O
- 批量操作:减少I/O次数
磁盘监控指标
javascript
// 查看磁盘I/O统计
db.serverStatus().wiredTiger.cache.
// 查看操作等待时间
db.serverStatus().globalLock.activeClients.
// 查看慢查询
db.system.profile.find({millis: {$gt: 100}}).sort({millis: -1})复制集的物理架构
复制集数据同步
- 初始同步:新节点加入时的全量同步
- ** oplog 复制**:增量同步,通过oplog实现
- 心跳机制:节点间定期通信
- 选举机制:主节点选举
复制集文件共享
- 每个节点有独立的数据目录
- 节点间通过网络同步数据
- 没有共享磁盘
复制集故障恢复
- 自动故障切换:主节点故障时自动选举
- 数据恢复:从最近的检查点恢复
- ** oplog 重放**:恢复未持久化的数据
分片集群的物理架构
分片数据分布
- 分片键:决定数据分布的字段
- 块(Chunk):数据的基本单位,默认64MB
- 均衡器:自动平衡各分片的块分布
- 分片键范围:每个块对应一个分片键范围
分片集群存储结构
- 每个分片是一个独立的复制集
- 每个分片有自己的数据目录
- 配置服务器存储元数据
- mongos路由数据访问
分片集群的I/O考虑
- 分片键选择:影响数据分布和I/O模式
- 块大小:影响迁移效率和I/O
- 均衡器活动:可能导致额外I/O
- 跨分片查询:增加网络I/O
物理架构监控与诊断
监控工具
- MongoDB Atlas:云服务监控
- Ops Manager:企业级监控
- mongostat:实时状态监控
- mongotop:I/O热点监控
- db.serverStatus():服务器状态
诊断命令
javascript
// 查看存储引擎状态
db.serverStatus().storageEngine.
// 查看WiredTiger状态
db.serverStatus().wiredTiger.
// 查看集合统计信息
db.collection.stats().wiredTiger.
// 查看索引统计信息
db.collection.totalIndexSize()常见性能问题
I/O瓶颈:
- 症状:高I/O等待时间
- 解决方案:使用SSD、优化查询、启用压缩
内存不足:
- 症状:频繁的页面置换
- 解决方案:增加内存、优化缓存配置
索引失效:
- 症状:全表扫描
- 解决方案:创建合适的索引
锁竞争:
- 症状:高锁等待时间
- 解决方案:优化查询、减少事务范围
物理架构最佳实践
1. 存储规划
- 选择合适的存储设备:优先使用SSD
- 合理规划磁盘容量:预留足够空间
- 分离日志和数据文件:减少I/O竞争
- 使用RAID 10:提供冗余和性能
2. 存储引擎配置
- 启用数据压缩:根据数据类型选择合适的压缩算法
- 合理设置缓存大小:建议使用系统内存的50%
- 调整检查点频率:根据业务需求调整
- 启用加密:符合安全要求
3. 索引优化
- 创建合适的索引:根据查询模式
- 避免过多索引:每个索引都会增加写开销
- 使用覆盖索引:减少回表查询
- 定期重建索引:优化索引性能
4. 内存管理
- 监控内存使用:避免内存不足
- 优化查询:减少内存密集型操作
- 限制连接数:避免连接占用过多内存
- 使用连接池:优化连接管理
5. I/O优化
- 批量操作:减少I/O次数
- 优化查询:减少全表扫描
- 使用writeConcern:根据业务需求设置
- 监控I/O指标:及时发现问题
物理架构演进
MongoDB 版本演进
| 版本 | 主要改进 |
|---|---|
| 3.0 | 引入WiredTiger存储引擎 |
| 3.2 | WiredTiger成为默认存储引擎 |
| 3.4 | 增强地理空间索引 |
| 4.0 | 支持多文档事务 |
| 4.2 | 支持分布式事务 |
| 5.0 | 增强时间序列数据支持 |
| 6.0 | 增强查询性能和安全特性 |
未来发展趋势
- 更高效的存储格式
- 更好的压缩算法
- 增强的加密支持
- 更智能的缓存管理
- 更好的云原生支持
常见问题(FAQ)
Q1: MongoDB 使用什么默认存储引擎?
A1: MongoDB 3.2及以上版本默认使用WiredTiger存储引擎。
Q2: WiredTiger 支持哪些压缩算法?
A2: WiredTiger支持Snappy、Zlib和Zstd压缩算法。
Q3: MongoDB 的数据文件存放在哪里?
A3: 默认路径为/data/db(Linux/macOS)或C:\data\db(Windows),可以通过--dbpath参数修改。
Q4: 如何查看 MongoDB 的内存使用情况?
A4: 可以使用db.serverStatus().mem命令查看内存使用情况。
Q5: 如何优化 MongoDB 的 I/O 性能?
A5: 优化MongoDB I/O性能的方法包括:使用SSD、启用数据压缩、优化索引、批量操作、分离日志和数据文件等。
Q6: 什么是 Write Ahead Log (WAL)?
A6: WAL是一种数据持久化机制,写操作首先写入日志,然后写入内存,确保数据不会丢失。
Q7: 如何配置 WiredTiger 缓存大小?
A7: 可以通过storage.wiredTiger.engineConfig.cacheSizeGB参数配置WiredTiger缓存大小。
Q8: MongoDB 支持哪些索引类型?
A8: MongoDB支持单字段索引、复合索引、多键索引、地理空间索引、文本索引和哈希索引等。
Q9: 什么是检查点机制?
A9: 检查点是数据库的一致性快照,用于崩溃恢复,默认每60秒创建一次。
Q10: 如何监控 MongoDB 的物理架构性能?
A10: 可以使用MongoDB Atlas、Ops Manager、mongostat、mongotop等工具监控MongoDB的物理架构性能。
