MongoDB内部的存储原理

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 这篇文章详细介绍了MongoDB的内部存储原理,包括存储引擎WiredTiger的架构、btree与b+tree的比较、cache机制、page结构、写操作流程、checkpoint和WAL日志,以及分布式存储的架构。

存储引擎

本文介绍默认存储引擎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 修改的值,修改的值包括值更新和值删除,是一个无锁单向链表

写操作
  1. 遍历btree,找到需要更新的page
  2. 如果cache中没有对应的page,会从磁盘中加载page,键值对存入WT_ROW
  3. 如果是insert操作,更新WT_INSERT,如果是update/delete操作,更新WT_UPDATE
  4. 如果需要,将操作记录写入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 是 skiplist8
  • row1 和 row2之间对应的 insert 是 skiplist1
  • row2 和 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数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
2月前
|
存储 NoSQL MongoDB
数据的存储--MongoDB文档存储(二)
数据的存储--MongoDB文档存储(二)
70 2
|
1月前
|
存储 NoSQL 关系型数据库
【赵渝强老师】MongoDB的存储结构
MongoDB 是一个可移植的 NoSQL 数据库,支持跨平台运行。其逻辑存储结构包括数据库、集合和文档,而物理存储结构则由命名空间文件、数据文件和日志文件组成。视频讲解和示意图进一步解释了这些概念。
|
6月前
|
存储 监控 NoSQL
MongoDB索引解析:工作原理、类型选择及优化策略
MongoDB索引解析:工作原理、类型选择及优化策略
|
2月前
|
存储 NoSQL 关系型数据库
数据的存储--MongoDB文档存储(一)
数据的存储--MongoDB文档存储(一)
91 3
|
5月前
|
存储 NoSQL MongoDB
MongoDB 索引原理与索引优化
MongoDB 索引原理与索引优化
115 1
|
6月前
|
存储 JSON NoSQL
深入解析MongoDB的存储原理
深入解析MongoDB的存储原理
深入解析MongoDB的存储原理
|
7月前
|
存储 NoSQL MongoDB
【MongoDB 专栏】MongoDB 的 GridFS:存储与检索大文件
【5月更文挑战第10天】MongoDB's GridFS 是用于大规模数据和大文件存储的解决方案,它将文件分割成小块存储在不同文档中,以提升管理效率和避免性能问题。文件上传时记录元数据,通过唯一标识符实现快速检索。GridFS 提供高效存储、便捷检索和扩展性,适用于大文件管理。然而,应注意文件大小限制、数据一致性和性能优化。通过案例分析,展示了 GridFS 在实际应用中的优势和适用场景,为构建强大应用提供支持。
372 1
【MongoDB 专栏】MongoDB 的 GridFS:存储与检索大文件
|
7月前
|
监控 NoSQL 容灾
MongoDB复制集原理:高可用性与数据一致性的保障
【4月更文挑战第30天】MongoDB复制集提供高可用性和数据一致性,通过在多个服务器间复制数据。复制集包含主节点和从节点,写操作在主节点执行,然后异步复制到从节点。优势包括故障切换、数据冗余、负载均衡和容灾备份。当主节点故障,其他节点会选举新主节点,确保服务连续性。配置复制集涉及规划节点、配置复制集、初始化和监控维护。复制集是实现数据库可靠性的核心。
|
7月前
|
存储 JSON NoSQL
MongoDB的文档存储格式BSON和JSON的区别
MongoDB的文档存储格式BSON和JSON的区别
|
7月前
|
存储 NoSQL 关系型数据库
基于MongoDB实现聊天记录的存储
基于MongoDB实现聊天记录的存储
基于MongoDB实现聊天记录的存储