浅谈MongoDB内部的存储原理

 更新时间:2023年07月04日 08:53:40   作者:数据知道  
这篇文章主要介绍了浅谈MongoDB内部的存储原理,MongoDB是一个面向文档的数据库系统。使用C++编写,不支持SQL,但有自己功能强大的查询语法,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

存储引擎

本文介绍默认存储引擎WiredTiger

WiredTiger架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m6gvgNNr-1657024774196)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1226)]

WiredTiger的写操作会先写入Cache,并持久化到WAL(Write ahead log),每60s会做一次Checkpoint,将当前的数据持久化,每,产生一个新的快照。Wiredtiger连接初始化时,首先将数据恢复至最新的快照状态,然后根据Checkpoint恢复数据,以保证存储可靠性

btree与b+tree

虽然遍历数据的查询是相对常见的,但是 MongoDB 认为查询单个数据记录远比遍历数据更加常见,由于 B 树的非叶结点也可以存储数据,所以 查询一条数据所需要的平均随机 IO 次数会比 B+ 树少,使用 B 树的 MongoDB 在类似场景中的查询速度就会比 MySQL 快。

这里并不是说 MongoDB 并不能对数据进行遍历,我们在 MongoDB 中也可以使用范围来查询一批满足对应条件的记录,只是需要的时间会比 MySQL 长一些。MySQL 认为遍历数据的查询是常见的,所以它选择 B+ 树作为底层数据结构

cache

内部缓存和文件系统缓存,默认情况下内部缓存取50%(RAM-1 GB)或256M较大者,文件系统缓存使用所有当前可用的RAM。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6pKa5SR-1657024774197)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1227)]

Wiredtiger的Cache采用Btree的方式组织,每个Btree节点为一个page,root page是btree的根节点,internal page是btree的中间索引节点,leaf page是真正存储数据的叶子节点;btree的数据以page为单位按需从磁盘加载或写入磁盘,btree的每个page以文件里的extent形式(由文件offset + size标识)存储

page

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MUI3Noms-1657024774198)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1228)]

ROW_ARRAY: 每个数组单元(wt_row)存储的是这个 kv row 在存储在磁盘上的 page kv cell 行集合数据缓冲区偏移的位置和编码方式(这个位置和编码方式在 WT 上定义成一个 wt_cell 对象),通过这个信息偏移位置信息就可以访问到这一样在缓冲区中的 K/V 内容值 ROW_UPDATE_ARRAY: 一个 mvcc list 对象,mvcc_list 与 wt_row 是一一对应的,mvcc list 当中存储对 wt_row 修改的值,修改的值包括值更新和值删除,是一个无锁单向链表

写操作 遍历btree,找到需要更新的page如果cache中没有对应的page,会从磁盘中加载page,键值对存入WT_ROW如果是insert操作,更新WT_INSERT,如果是update/delete操作,更新WT_UPDATE如果需要,将操作记录写入journal

我们通过一个实例来说明: 假如一个 page 存储了一个 [0,100] 的 key 范围,磁盘上原来存储的行 key=2, 10 ,20, 30 , 50, 80, 90,他们的值分别是value = 102, 110, 120, 130, 150, 180, 190。 在 page 数据从磁盘读到内存后,分别对 key=2 的 value 进行了两次修改,两次修改的值是分别 402,502。对 key = 20 ,50 的 value 做了一次修改,修改后的 value = 122, 155,后有分配 insert 了新的 key = 3,5, 41, 99,value = 203,205,241,299。 那么在内存中的 page 就是如下图组织数据的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ew70Kjzs-1657024774198)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1229)]

相邻的两 wt_row 之间可能不是连续的,他们之间可以插入新的单元,例如 row1(key = 2) 和 row2(key=10) 可以插入 3 和 5,这两个 row 之间需要有一个排序的数据结构(WT用 skiplist 数据结构)来存储插入的 K/V,就需要一个 skiplist 对象数组 page_insert_array与row array对应。这里需要说明的是 图6 当中红色框当中的 skiplist8,它是用于存储 row1(key=2) 范围之前的 insert 数据,图中如果有 key =1 的数据 insert,那么这个数据会新增到 skiplist8 当中。

那么图中row与 insert skiplist 的对应关系就是:

row1 之前的范围对应 insert 是 skiplist8row1 和 row2之间对应的 insert 是 skiplist1row2 和 row3之间对应的 insert 是 skiplist3…row7 之后的范围对应的 insert 是 skiplist7 checkpoint

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAoNj9By-1657024774199)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1230)]

一个Checkpoit包含如下元数据: root page地址,地址由文件offset,size及内容的checksum组成 alloc extent list地址,存储从上次checkpoint起新分配的extent列表 discard extent list地址,存储从上次checkpoint起丢弃的extent列表 available extent list地址,存储可分配的extent列表,只有最新的checkpoint包含该列表 file size 如需恢复到该checkpoint的状态,将文件truncate到file size即可

WAL(journal)

日志文件记录的是从上一个checkpoint之后的实际操作,该文件每100ms或文件大小到达100M就从缓存同步到磁盘

整体关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVHYqJxR-1657024774199)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1231)]

分布式存储

架构

架构图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFTkWPep-1657024774200)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1232)]

写数据流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBfsoU1L-1657024774200)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1233)]

读数据流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IDG49n7y-1657024774201)(evernotecid://B1CD39FE-B044-413D-A086-0649DB3F0070/appyinxiangcom/26430792/ENResource/p1234)]

到此这篇关于浅谈MongoDB内部的存储原理的文章就介绍到这了,更多相关MongoDB存储原理内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • 详解MongoDB数据库基础操作及实例

    详解MongoDB数据库基础操作及实例

    这篇文章主要介绍了详解MongoDB数据库基础操作及实例的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-09-09
  • MongoDB视图的修改与删除的实现

    MongoDB视图的修改与删除的实现

    视图为mongodb的操作和数据安全上提供了便利,本文主要介绍了MongoDB视图的修改与删除的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • mac下安装和配置mongodb的步骤详解

    mac下安装和配置mongodb的步骤详解

    大家都知道MongoDB是一个跨平台的,面向文档的数据库,提供高性能,高可用性和可扩展性方便。那么下面这篇文章就来给大家介绍了关于在mac系统下安装和配置mongodb的方法步骤,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-07-07
  • 教大家8天学通MongoDB——第一天 基础入门篇

    教大家8天学通MongoDB——第一天 基础入门篇

    MongoDB是目前非常流行的一种非关系型数据库(NoSQL),因其操作简单、完全免费、源码公开等特点,受到了IT从业人员的青睐,并被广泛部署于实际的生产环境中。本文教大家8天学通MongoDB——第一天 基础入门篇,感兴趣的朋友一起来了解了解吧
    2015-09-09
  • 使用Node操作MongoDB数据库的方法

    使用Node操作MongoDB数据库的方法

    这篇文章主要介绍了使用Node操作MongoDB数据库的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-01-01
  • MongoDB中的加减乘除运算详解

    MongoDB中的加减乘除运算详解

    这篇文章主要给大家介绍了关于MongoDB中加减乘除运算的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • 在阿里云centos下部署mongodb教程

    在阿里云centos下部署mongodb教程

    这里给大家分享的是作者在阿里云centos下部署mongodb的过程全记录,非常的详细,也遇到了很多问题,最终部署成功,希望对大家能够有所帮助
    2017-08-08
  • Linux服务器快速安装MongoDB5.0版本过程步骤

    Linux服务器快速安装MongoDB5.0版本过程步骤

    这篇文章主要为大家介绍了Linux服务器快速安装MongoDB5.0版本过程步骤详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • MongoDB 管道的介绍及操作符实例

    MongoDB 管道的介绍及操作符实例

    这篇文章主要介绍了MongoDB 管道的介绍及操作符实例的相关资料,MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理,需要的朋友可以参考下
    2017-07-07
  • MongoDB通配符索引的用法实例

    MongoDB通配符索引的用法实例

    这篇文章主要给大家介绍了关于MongoDB通配符索引的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论

?


http://www.vxiaotou.com