掘金 后端 ( ) • 2021-07-12 15:53
.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:30px;margin-bottom:5px}.markdown-body h2{padding-bottom:12px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}

前言

与 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 的配置文件的一些参数设置。