mongodb存储引擎wired tiger学习笔记

从MongoDB 3.2 版本开始,WiredTiger成为MongDB默认的Storage Engine,用于将数据持久化存储到硬盘文件中,WiredTiger提供文档级别(Document-Level)的并发控制,检查点(CheckPoint),数据压缩和本地数据加密( Native Encryption)等功能。

特性

1. checkpoint

Checkpoint操作开始时,WiredTiger提供指定时间点(point-in-time)的数据库快照(Snapshot),该Snapshot呈现的是内存中数据的一致性视图。当向Disk写入数据时,WiredTiger将Snapshot中的所有数据以一致性方式写入到数据文件(Disk Files)中。一旦Checkpoint创建成功,WiredTiger保证数据文件和内存数据是一致性的,因此,Checkpoint担当的是还原点(Recovery Point),Checkpoint操作能够缩短MongoDB从Journal日志文件还原数据的时间。

当WiredTiger创建Checkpoint时,MongoDB将数据刷新到数据文件(Disk Files)中,在默认情况下,WiredTiger创建Checkpoint的时间间隔是60s,或产生2GB的Journal文件。在WiredTiger创建新的Checkpoint期间,上一个Checkpoint仍然是有效的,这意味着,即使MongoDB在创建新的Checkpoint期间遭遇到错误而异常终止运行,只要重启,MongoDB就能从上一个有效的Checkpoint开始还原数据。

如果要还原在上一个Checkpoint之后执行的修改操作,必须使用Journal日志文件

2. 预写日志journal

Journal 是顺序写入的日志文件,用于记录上一个Checkpoint之后发生的数据更新,能够将数据库从系统异常终止事件中还原到一个有效的状态。在数据更新时,先将数据更新写入到journal文件。journal文件会首先写入内存中。所有不超过128kb的日志记录都被缓存。当满足以下条件时,journal会被刷入到磁盘中:

- 每100ms
- 写操作时加了选项`{j:true}`
- 达到创建新的journal文件的阈值(100mb)

使用Journal日志文件还原的过程

WiredTiger创建Checkpoint,能够将MongoDB数据库还原到上一个CheckPoint创建时的一致性状态,如果MongoDB在上一个Checkpoint之后异常终止,必须使用Journal日志文件,重做从上一个Checkpoint之后发生的数据更新操作,将数据还原到Journal记录的一致性状态,使用Journal日志还原的过程是:
1 获取上一个Checkpoint创建的标识值:从数据文件(Data Files)中查找上一个Checkpoint发生的标识值(Identifier);
2 根据标识值匹配日志记录:从Journal Files 中搜索日志记录(Record),查找匹配上一个Checkpoint的标识值的日志记录;
3 重做日志记录:重做从上一个Checkpoint之后,记录在Journal Files中的所有日志记录;

3.存储结构

数据存储

内存page以B+树的结构组织,每个节点为一个page,root page是btree的根节点,internal page是btree的中间索引节点,leaf page是真正存储数据的叶子节点;btree的数据以page为单位按需从磁盘加载或写入磁盘。

Wiredtiger采用Copy on write(快照)的方式管理修改操作(insert、update、delete),修改操作会先缓存在cache里,checkpoint时,会产生一个新的root page,此时对页面的修改会新分配索引page和数据page。原来的B+树结构实际成为一个快照,由后台线程执行checkpoint

索引存储

Mongo在索引上也区分为主键索引和非主键索引,这方面与Mysql的聚簇索引和二级索引类似,主键索引储存主键以及数据内容,非主键索引储存索引列数据以及主键。

  • 搜索从根节点开始,由于B树所有节点都会负责数据存储的工作。所以搜索的时间复杂度和数据在结构中的位置强相关,最好的状态是数据在根节点中就搜索到了,可以直接返回,时间复杂度是O(1)。即从平均搜索速度来看MongoDB查询速度会比Mysql更快
  • 单纯从存储结构上看,数据的存储分布在各个节点,因此如果需要对数据进行遍历,则需要对整个树进行数据的读取。但是从整体的角度层面来看,MongoDB的数据是结构化存储,所有的数据都可以以聚合的方式进行存储,对于数据的遍历需求并没有关系型数据库那么高。在数据的存储底层,Mongo使用的也是BSON(Binary Json)进行存储,在类型支持和网络传输效率上相较于Json也有了很大的提升。

MongoDB是一种面向文档的数据库管理系统,与传统关系型数据库譬如Mysql不同的是Mysql的数据是扁平化的,构建结构化的数据往往需要通过连表查询在业务中进行组合。而MongoDB是面向文档的数据库,数据在存储阶段就是结构化的,聚合的。即一个文档内部就包含了其相关联的子结构

空间局部性原理:如果一个存储器的某个位置被访问,那么将它附近的位置也会被访问。
B+树叶节点两两相连可大大增加区间访问性,可使用在范围查询等,而B-树每个节点 key 和 data 在一起,则无法区间查找。

B+树可以很好的利用局部性原理,若我们访问节点 key为 50,则 key 为 55、60、62 的节点将来也可能被访问,我们可以利用磁盘预读原理提前将这些数据读入内存,减少了磁盘 IO 的次数。 
当然B+树也能够很好的完成范围查询。比如查询 key 值在 50-70 之间的节点。

你可能感兴趣的:(mongodb)