外观
MongoDB 存储架构
存储引擎架构
存储引擎类型
WiredTiger:默认存储引擎(MongoDB 3.2+)
- 支持文档级并发控制
- 提供压缩选项(snappy、zlib、zstd)
- 支持快照隔离
- 适合大多数生产环境
In-Memory:内存存储引擎
- 数据完全存储在内存中
- 提供低延迟访问
- 适合缓存和临时数据场景
MMAPv1:旧版默认存储引擎(已废弃)
- 基于内存映射文件
- 集合级锁
- 不推荐在生产环境使用
存储引擎选择
| 场景 | 推荐存储引擎 | 理由 |
|---|---|---|
| 一般生产环境 | WiredTiger | 文档级锁、压缩、高性能 |
| 低延迟要求 | In-Memory | 内存访问,延迟最低 |
| 只读/缓存场景 | In-Memory | 适合频繁读取的场景 |
| 历史系统迁移 | MMAPv1 | 仅用于迁移,不推荐新部署 |
数据文件结构
主要数据文件
.wt文件:WiredTiger存储引擎的数据文件
WiredTiger.wt:存储引擎元数据sizeStorer.wt:存储集合和索引的大小信息collection-*.wt:集合数据文件index-*.wt:索引数据文件
journal目录:事务日志文件
- 确保写操作的持久性
- 每个日志文件大小默认128MB
- 定期进行检查点(checkpoint)操作
diagnostic.data目录:诊断数据
- 存储崩溃信息
- 用于故障诊断和分析
文件组织
数据存储机制
文档存储格式
BSON格式:Binary JSON,MongoDB的底层存储格式
- 支持更多数据类型(Date、Binary、ObjectId等)
- 固定大小的元素,便于快速遍历
- 紧凑的二进制表示,节省存储空间
文档压缩:
- snappy:默认压缩算法,平衡压缩比和性能
- zlib:更高压缩比,适合冷数据
- zstd:MongoDB 4.2+支持,提供更好的压缩比和性能
yaml
# 启用文档压缩
storage:
wiredTiger:
collectionConfig:
blockCompressor: zstd索引存储
B树索引结构:
- 平衡树结构,支持高效的范围查询
- 每个节点存储多个键值对
- 根节点和内部节点仅存储索引键和指针
- 叶子节点存储完整的索引键和文档位置
索引压缩:
- 前缀压缩:减少重复索引键的存储
- 块压缩:使用与集合相同的压缩算法
yaml
# 启用索引压缩
storage:
wiredTiger:
indexConfig:
prefixCompression: true数据页管理
页大小:默认16KB(可配置)
页类型:
- 数据页:存储文档数据
- 索引页:存储索引数据
- 溢出页:存储大文档
页缓存:
- WiredTiger使用自己的缓存管理
- 默认使用系统内存的50%
- 可通过
wiredTiger.engineConfig.cacheSizeGB配置
日志管理
Write Ahead Log (WAL)
作用:确保写操作的持久性
写入流程:
- 写操作先写入WAL日志
- 日志写入磁盘后,操作才返回成功
- 定期将内存中的数据刷新到数据文件
日志配置:
yaml
storage:
journal:
enabled: true
commitIntervalMs: 100 # 日志提交间隔
directoryPerDB: false # 每个数据库单独的日志目录检查点机制
作用:将内存中的数据快照刷新到磁盘
触发条件:
- 每60秒自动触发
- 日志文件达到128MB时触发
- 手动执行
db.runCommand({ checkpoint: 1 })
检查点流程:
- 创建数据快照
- 将快照数据写入磁盘
- 更新元数据,标记检查点完成
存储优化
数据压缩优化
选择合适的压缩算法:
- 热数据:使用snappy或zstd
- 冷数据:使用zlib
- 根据数据特性进行测试选择
压缩效果监控:
javascript
// 查看压缩效果
db.collection.stats().wiredTiger.block-manager.compression-ratio存储引擎缓存优化
- 缓存大小调整:
- 根据系统内存大小调整
- 建议为其他进程预留足够内存
- 监控缓存使用率,避免缓存不足
yaml
# 配置缓存大小
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 8 # 设置为8GB文件系统优化
文件系统选择:
- Linux:推荐XFS或EXT4
- Windows:NTFS
- macOS:APFS或HFS+
文件系统挂载选项:
noatime:禁用访问时间更新nodiratime:禁用目录访问时间更新- 调整I/O调度器(如使用deadline或none)
大文档处理
文档大小限制
- MongoDB单文档大小限制为16MB
- 超过限制的文档需要特殊处理:
- 使用GridFS存储
- 拆分为多个文档
- 存储外部引用
GridFS机制
组成部分:
fs.files:存储文件元数据fs.chunks:存储文件数据块(默认255KB)
使用场景:
- 存储大型文件(如图片、视频)
- 需要查询文件元数据
- 需要原子性的文件操作
bash
# 使用mongofiles上传文件
mongofiles --host mongodb:27017 --db test put large-file.zip
# 下载文件
mongofiles --host mongodb:27017 --db test get large-file.zip存储监控与维护
存储监控指标
存储使用率:
dbStats.dataSize:数据大小dbStats.storageSize:存储大小(压缩后)dbStats.indexSize:索引大小
缓存指标:
wiredTiger.cache.bytes currently in the cachewiredTiger.cache.percent dirty pages in the cachewiredTiger.cache.pages evicted by application threads
I/O指标:
disk.io.readsdisk.io.writesdisk.io.readWaitdisk.io.writeWait
存储维护操作
- 碎片整理:javascript
// 整理集合碎片
db.collection.reIndex() // 重建索引 db.collection.compact() // 压缩集合
- **检查点管理**:
```javascript
// 手动触发检查点
db.runCommand({ checkpoint: 1 })- 日志管理:javascript
// 查看日志状态
db.adminCommand({ getLog: 'journal' })
## 常见问题(FAQ)
### Q1: WiredTiger和MMAPv1的主要区别是什么?
A1: WiredTiger和MMAPv1的主要区别:
- 锁粒度:WiredTiger是文档级锁,MMAPv1是集合级锁
- 压缩:WiredTiger支持多种压缩算法,MMAPv1不支持
- 并发性能:WiredTiger支持更高的并发写入
- 内存管理:WiredTiger有自己的缓存管理,MMAPv1依赖操作系统
### Q2: 如何选择合适的压缩算法?
A2: 压缩算法选择建议:
- **snappy**:默认选项,平衡压缩比和性能
- **zlib**:更高的压缩比,适合冷数据
- **zstd**:MongoDB 4.2+支持,提供更好的压缩比和性能
- 建议根据数据特性进行测试,选择最适合的压缩算法
### Q3: 存储引擎缓存设置多少合适?
A3: 缓存大小建议:
- 默认使用系统内存的50%
- 为其他进程预留足够内存(至少2GB)
- 对于专用MongoDB服务器,可以设置为系统内存的60-80%
- 监控缓存使用率,避免缓存不足导致频繁的页交换
### Q4: 什么是检查点(checkpoint)?
A4: 检查点是WiredTiger存储引擎的一个重要机制:
- 将内存中的数据快照刷新到磁盘
- 确保数据一致性
- 减少恢复时间
- 每60秒自动触发,或日志文件达到128MB时触发
### Q5: 如何处理超过16MB的大文档?
A5: 处理大文档的方法:
- 使用GridFS存储大型文件
- 将大文档拆分为多个相关文档
- 存储外部引用,将实际数据存储在文件系统
- 优化文档结构,减少不必要的数据
### Q6: 如何监控存储引擎性能?
A6: 监控存储引擎性能的方法:
- 使用`db.serverStatus().wiredTiger`查看WiredTiger状态
- 使用`db.collection.stats()`查看集合存储统计
- 使用MongoDB Atlas或Ops Manager监控
- 使用第三方监控工具(如Prometheus + Grafana)
- 关注缓存使用率、I/O等待时间、压缩比率等指标