Skip to content

MongoDB 物理架构

WiredTiger 存储引擎

WiredTiger 核心特性

  1. 文档级并发控制

    • 支持多个并发写操作
    • 减少锁竞争
    • 提高系统吞吐量
  2. 数据压缩

    • 支持Snappy、Zlib和Zstd压缩算法
    • 减少磁盘空间占用
    • 降低I/O操作
  3. 加密支持

    • 静态数据加密
    • 传输数据加密
    • 符合安全合规要求
  4. 检查点机制

    • 定期创建一致性检查点
    • 支持快速恢复
    • 减少数据丢失风险

WiredTiger 数据结构

1. B树索引

WiredTiger使用B树作为主要的索引结构:

2. LSM树(可选)

WiredTiger也支持LSM树(日志结构合并树),适用于写入密集型场景。

WiredTiger 缓存机制

WiredTiger使用两级缓存机制:

  1. WiredTiger缓存

    • 存储热点数据
    • 大小由storage.wiredTiger.engineConfig.cacheSizeGB参数控制
    • 默认使用系统内存的50%
  2. 操作系统页缓存

    • 由操作系统管理
    • 存储频繁访问的数据页
    • 补充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. 哈希索引

  • 基于哈希函数
  • 仅支持等值查询
  • 不支持范围查询

索引存储优化

  1. 索引压缩

    • WiredTiger支持索引压缩
    • 减少索引占用空间
    • 提高索引访问效率
  2. 索引前缀截断

    • 对于长字符串,仅存储前缀
    • 减少索引大小
    • 提高查询效率
  3. 覆盖索引

    • 索引包含查询所需的所有字段
    • 避免回表查询
    • 提高查询性能

数据持久化机制

Write Ahead Log (WAL)

WiredTiger使用Write Ahead Log确保数据持久性:

  1. 写操作首先写入WAL日志
  2. 然后写入内存缓存
  3. 定期将内存中的数据刷新到磁盘

检查点机制

检查点是数据库的一致性快照:

  1. 定期创建(默认每60秒或每2GB日志)
  2. 记录所有已提交的事务
  3. 用于崩溃恢复
  4. 提高恢复速度

数据刷新策略

  1. 定期刷新:默认每60秒
  2. 日志大小触发:当日志达到一定大小
  3. 手动触发:使用fsync命令
  4. 事务提交:对于同步写关注

内存管理

MongoDB 内存结构

MongoDB的内存使用可以分为以下几个部分:

  1. WiredTiger缓存:存储热点数据和索引
  2. 操作系统页缓存:缓存磁盘数据页
  3. 连接内存:每个连接使用的内存
  4. 操作内存:执行操作所需的内存
  5. 聚合管道内存:聚合操作使用的内存

内存配置参数

yaml
# WiredTiger缓存大小
storage:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 4

# 连接数限制
net:
  maxIncomingConnections: 65536

# 操作内存限制
operationProfiling:
  mode: slowOp
  slowOpThresholdMs: 100

内存优化建议

  1. 合理设置缓存大小:根据系统内存调整
  2. 监控内存使用:使用db.serverStatus().mem查看
  3. 优化查询:减少内存密集型操作
  4. 使用索引:减少全表扫描
  5. 限制连接数:避免过多连接占用内存

磁盘I/O优化

I/O 模式

MongoDB的I/O模式主要包括:

  1. 顺序写:WAL日志的写入
  2. 随机读:数据检索
  3. 顺序读:全表扫描或范围查询

I/O 优化策略

  1. 使用高速存储设备:SSD优于HDD
  2. 合理配置RAID:RAID 10适合MongoDB
  3. 分离日志和数据文件:减少I/O竞争
  4. 启用数据压缩:减少I/O操作
  5. 优化索引:减少随机I/O
  6. 批量操作:减少I/O次数

磁盘监控指标

javascript
// 查看磁盘I/O统计
 db.serverStatus().wiredTiger.cache.

// 查看操作等待时间
 db.serverStatus().globalLock.activeClients.

// 查看慢查询
 db.system.profile.find({millis: {$gt: 100}}).sort({millis: -1})

复制集的物理架构

复制集数据同步

  1. 初始同步:新节点加入时的全量同步
  2. ** oplog 复制**:增量同步,通过oplog实现
  3. 心跳机制:节点间定期通信
  4. 选举机制:主节点选举

复制集文件共享

  • 每个节点有独立的数据目录
  • 节点间通过网络同步数据
  • 没有共享磁盘

复制集故障恢复

  1. 自动故障切换:主节点故障时自动选举
  2. 数据恢复:从最近的检查点恢复
  3. ** oplog 重放**:恢复未持久化的数据

分片集群的物理架构

分片数据分布

  1. 分片键:决定数据分布的字段
  2. 块(Chunk):数据的基本单位,默认64MB
  3. 均衡器:自动平衡各分片的块分布
  4. 分片键范围:每个块对应一个分片键范围

分片集群存储结构

  • 每个分片是一个独立的复制集
  • 每个分片有自己的数据目录
  • 配置服务器存储元数据
  • mongos路由数据访问

分片集群的I/O考虑

  1. 分片键选择:影响数据分布和I/O模式
  2. 块大小:影响迁移效率和I/O
  3. 均衡器活动:可能导致额外I/O
  4. 跨分片查询:增加网络I/O

物理架构监控与诊断

监控工具

  1. MongoDB Atlas:云服务监控
  2. Ops Manager:企业级监控
  3. mongostat:实时状态监控
  4. mongotop:I/O热点监控
  5. db.serverStatus():服务器状态

诊断命令

javascript
// 查看存储引擎状态
 db.serverStatus().storageEngine.

// 查看WiredTiger状态
 db.serverStatus().wiredTiger.

// 查看集合统计信息
 db.collection.stats().wiredTiger.

// 查看索引统计信息
 db.collection.totalIndexSize()

常见性能问题

  1. I/O瓶颈

    • 症状:高I/O等待时间
    • 解决方案:使用SSD、优化查询、启用压缩
  2. 内存不足

    • 症状:频繁的页面置换
    • 解决方案:增加内存、优化缓存配置
  3. 索引失效

    • 症状:全表扫描
    • 解决方案:创建合适的索引
  4. 锁竞争

    • 症状:高锁等待时间
    • 解决方案:优化查询、减少事务范围

物理架构最佳实践

1. 存储规划

  • 选择合适的存储设备:优先使用SSD
  • 合理规划磁盘容量:预留足够空间
  • 分离日志和数据文件:减少I/O竞争
  • 使用RAID 10:提供冗余和性能

2. 存储引擎配置

  • 启用数据压缩:根据数据类型选择合适的压缩算法
  • 合理设置缓存大小:建议使用系统内存的50%
  • 调整检查点频率:根据业务需求调整
  • 启用加密:符合安全要求

3. 索引优化

  • 创建合适的索引:根据查询模式
  • 避免过多索引:每个索引都会增加写开销
  • 使用覆盖索引:减少回表查询
  • 定期重建索引:优化索引性能

4. 内存管理

  • 监控内存使用:避免内存不足
  • 优化查询:减少内存密集型操作
  • 限制连接数:避免连接占用过多内存
  • 使用连接池:优化连接管理

5. I/O优化

  • 批量操作:减少I/O次数
  • 优化查询:减少全表扫描
  • 使用writeConcern:根据业务需求设置
  • 监控I/O指标:及时发现问题

物理架构演进

MongoDB 版本演进

版本主要改进
3.0引入WiredTiger存储引擎
3.2WiredTiger成为默认存储引擎
3.4增强地理空间索引
4.0支持多文档事务
4.2支持分布式事务
5.0增强时间序列数据支持
6.0增强查询性能和安全特性

未来发展趋势

  1. 更高效的存储格式
  2. 更好的压缩算法
  3. 增强的加密支持
  4. 更智能的缓存管理
  5. 更好的云原生支持

常见问题(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的物理架构性能。