MongoDB 不专业指北(十五):WiredTiger存储引擎

1,517 阅读3分钟

前言

与 MySQL 一样,MongoDB 也有不同类型的存储引擎,不同的存储引擎解决不同场景的问题。创建数据库或数据集时可以指定存储引擎,如下所示:

// 数据集创建指定存储引擎
db.createCollection(
   'users',
   { storageEngine: { wiredTiger: { configString: "access_pattern_hint=random" } } }
);
// 数据库目录指定存储引擎
mongod --storageEngine wireTiger --dbpath <数据库路径>

自 MongoDB 3.2以后,默认的存储引擎为 WiredTiger,本篇介绍 WiredTiger 的特性。

文档级并发

WiredTiger 存储引擎在写操作时使用文档级的并发控制,因此,多个客户端可以同时修改同一数据集的文档(有点类似行锁)。 ​

对于大多数的读写操作,WiredTiger 使用优化后的并发控制。WiredTiger 在全局、数据库和数据集使用意图锁(intent lock)。当存储引擎检测到两个操作的冲突后,其中导致写冲突的操作会让 MongoDB 重试该操作。

更新机制

在 WiredTiger 引擎中,没有基于原文档的更新。如果你要更新文档的一个元素,实际上是插入了全新的文档,而就文档会被删除。

快照和检测点

WiredTiger 使用多版本并发控制(MVCC)。在一个操作的起点,WiredTiger 提供了要操作数据的时间点快照。快照代表了内存中的一个连续的数据段。 当向磁盘写数据时,WIredTiger 将快照的数据持续写入到磁盘。当前可用的数据就如同数据文件的一个检测点。检测点保证了数据文件是连续的,并且包含了上一个检测点,因此检测点可以视作恢复点。在写入新的检测点的过程中,之前的检测点依旧是有效的。因此,即便是 MongoDB 在写入新的检测点时发生错误而中止写入过程,重启后,MongoDB 也可以从上一个有效的检测点恢复数据。 当 WiredTiger 的元素数据表自动更新指向到新的检测点后,新的检测点才可用。一旦新的检测点可用,WiredTIger 可以将旧的检测点的存储空间释放。

数据压缩

基于 WiredTiger,MongoDB 支持对所有的数据集和索引进行压缩。压缩可以占用一点 CPU 资源完成存储空间的缩小。WiredTiger 默认使用 Snappy 压缩库(压缩率比如 zlib,但占用 CPU 资源更少)对数据集做块压缩,而对索引使用前缀压缩(prefix compression)。对于数据集,也可以使用 zlib 或 zstd(4.2版本以后)压缩库。 指定数据集的压缩算法可以在创建数据集时指定,如下所示:

// 创建数据集时指定 zlib 为压缩库
db.createCollection('users', { 
  storageEngine: {
    wiredTiger: {
      configString: 'block_compressor=zlib'
    }
  }
});

// 开启索引压缩
db.employees.createIndex({age: 1}, {
    storageEngine: {
      wiredTiger: {
         configString: 'prefix_compression=true'
      }
   }
});

总结

本篇介绍了 MongoDB 默认的存储引擎WiredTiger的特性,通过配置存储引擎的一些参数可以进行调优,取得存储与性能上的平衡。接下来我们介绍 MongoDB 的配置文件的一些参数设置。