MongoDB 底层原理

MongoDB 底层原理

MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持无模式的数据建模,可以存储比较复杂的数据类型,是一款非常流行的文档类型数据库

在高负载的情况下,MongoDB 天然支持水平扩展和高可用,可以很方便地添加更多的节点/实例,以保证服务性能和可用性。在许多场景下,MongoDB 可以用于代替传统的关系型数据库或键/值存储方式,皆在为 Web 应用提供可扩展的高可用高性能数据存储解决方案

存储结构

MongoDB 的存储结构区别于传统的关系型数据库,主要由如下三个单元组成:

  • 文档(Document) :MongoDB 中最基本的单元,由 BSON 键值对(key-value)组成,类似于关系型数据库中的行(Row)
  • 集合(Collection) :一个集合可以包含多个文档,类似于关系型数据库中的表(Table)。集合存在于数据库中,没有固定的结构,也就是无模式的,这意味着可以往集合插入不同格式和类型的数据
  • 数据库(Database) :一个数据库中可以包含多个集合,可以在 MongoDB 中创建多个数据库,类似于关系型数据库中的数据库(Database)

MongoDB 将数据记录存储为文档 (更具体来说是BSON 文档),这些文档在集合中聚集在一起,数据库中存储一个或多个文档集合

BSON

MongoDB 中的记录就是一个 BSON 文档,它是由键值对组成的数据结构,类似于 JSON 对象,是 MongoDB 中的基本数据单元。字段的值可能包括其他文档、数组和文档数组。MongoDB 和 ES 中存放的数据形式类似,但是其使用又和 ES 不一样,Mongo 可以支持事务、持久化同时默认模式下是单机 DB

文档的键是字符串。除了少数例外情况,键可以使用任意 UTF-8 字符

键不能含有 \0(空字符)。这个字符用来表示键的结尾。

. 和 $ 有特别的意义,只有在特定环境下才能使用。

以下划线_开头的键是保留的(不是严格要求的)

BSON [bee·sahn] 是 Binary JSON的简称,是 JSON 文档的二进制表示,支持将文档和数组嵌入到其他文档和数组中,还包含允许表示不属于 JSON 规范的数据类型的扩展

根据维基百科对 BJSON 的介绍,BJSON 的遍历速度优于 JSON,这也是 MongoDB 选择 BSON 的主要原因,但 BJSON 需要更多的存储空间

与 JSON 相比,BSON 着眼于提高存储和扫描效率。BSON 文档中的大型元素以长度字段为前缀以便于扫描。在某些情况下,由于长度前缀和显式数组索引的存在,BSON 使用的空间会多于 JSON

数据库

数据库用于存储所有集合,而集合又用于存储所有文档。一个 MongoDB 中可以创建多个数据库,每一个数据库都有自己的集合和权限。MongoDB 预留了几个特殊的数据库

特殊的数据库

  • admin : admin 数据库主要是保存 root 用户和角色。例如,system.users 表存储用户,system.roles 表存储角色。一般不建议用户直接操作这个数据库。将一个用户添加到这个数据库,且使它拥有 admin 库上的名为 dbAdminAnyDatabase 的角色权限,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如关闭服务器
  • local : local 数据库是不会被复制到其他分片的,因此可以用来存储本地单台服务器的任意 collection。一般不建议用户直接使用 local 库存储任何数据,也不建议进行 CRUD 操作,因为数据无法被正常备份与恢复
  • config : 当 MongoDB 使用分片设置时,config 数据库可用来保存分片的相关信息
  • test : 默认创建的测试库,连接 mongod 服务时,如果不指定连接的具体数据库,默认就会连接到 test 数据库

事务

NoSQL 数据库通常不支持事务,为了可扩展和高性能进行了权衡。不过,也有例外,MongoDB 就支持事务。与关系型数据库一样,MongoDB 事务同样具有 ACID 特性。MongoDB 单文档原生支持原子性,也具备事务的特性

MongoDB 4.0 加入了对多文档事务的支持,但只支持复制集部署模式下的事务,也就是说事务的作用域限制为一个副本集内。MongoDB 4.2 引入了分布式事务,增加了对分片集群上多文档事务的支持,并合并了对副本集上多文档事务的现有支持

WiredTiger 存储引擎支持 read-uncommitted 、read-committed 和 snapshot3 种事务隔离级别,MongoDB 启动时默认选择 snapshot 隔离

其底层原理和 Mysql 类似,使用日志、MVCC、写锁来支持事务,其落库时机等等都差不多

存储引擎

存储引擎(Storage Engine)是数据库的核心组件,负责管理数据在内存和磁盘中的存储方式

与 MySQL 一样,MongoDB 采用的也是插件式的存储引擎架构 ,支持不同类型的存储引擎,不同的存储引擎解决不同场景的问题。在创建数据库或集合时,可以指定存储引擎

插件式的存储引擎架构可以实现 Server 层和存储引擎层的解耦,可以支持多种存储引擎,如 MySQL 既可以支持 B-Tree 结构的 InnoDB 存储引擎,还可以支持 LSM 结构的 RocksDB 存储引擎

在存储引擎刚出来的时候,默认是使用 MMAPV1 存储引擎,MongoDB4.x 版本不再支持 MMAPv1 存储引擎。

现在主要有下面这两种存储引擎:

  • WiredTiger 存储引擎 :自 MongoDB 3.2 以后,默认的存储引擎为 WiredTiger 存储引擎 。非常适合大多数工作负载,建议用于新部署。WiredTiger 提供文档级并发模型、检查点和数据压缩(后文会介绍到)等功能
  • In-Memory 存储引擎 :In-Memory 存储引擎在 MongoDB Enterprise 中可用。它不是将文档存储在磁盘上,而是将它们保留在内存中以获得更可预测的数据延迟,行为模式类似 redis

此外,MongoDB 3.0 提供了 可插拔的存储引擎 API ,允许第三方为 MongoDB 开发存储引擎,这点和 MySQL 也比较类似

目前绝大部分流行的数据库存储引擎都是基于 B/B+ Tree 或者 LSM(Log Structured Merge,是一种数据存储结构的设计思想,核心目的是将随机写转化为顺序写,从而极大提升写入性能) Tree 来实现的。对于 NoSQL 数据库来说,绝大部分(比如 HBase、Cassandra、RocksDB)都是基于 LSM 树,MongoDB 不太一样,使用的是 B+ 树作为其存储结构

为什么 MongoDB 会使用 B+ 树:https://mp.weixin.qq.com/s/mMWdpbYRiT6LQcdaj4hgXQ

索引

支持多种类型的索引 :MongoDB 支持多种类型的索引,包括单字段索引、复合索引、多键索引、哈希索引、文本索引、 地理位置索引等,每种类型的索引有不同的使用场合。

MongoDB 的复合索引遵循左前缀原则,拥有多个键的索引,可以同时得到所有这些键的前缀组成的索引,但不包括除左前缀之外的其他子集。比如说,有一个类似 {a: 1, b: 1, c: 1, ..., z: 1} 这样的索引,那么实际上也等于有了 {a: 1}、{a: 1, b: 1}、{a: 1, b: 1, c: 1} 等一系列索引,但是不会有 {b: 1} 这样的非左前缀的索引

同时还支持 TTL 索引(索引一段时间后会过期)和覆盖索引(避免回表消耗)

其他特性

支持 mapreduce :通过分治的方式完成复杂的聚合任务。不过,从 MongoDB 5.0 开始,map-reduce 已经不被官方推荐使用了,替代方案是 聚合管道。聚合管道提供比 map-reduce 更好的性能和可用性

支持 failover :提供自动故障恢复的功能,主节点发生故障时,自动从从节点中选举出一个新的主节点,确保集群的正常使用,这对于客户端来说是无感知的

支持分片集群 :MongoDB 支持集群自动切分数据,让集群存储更多的数据,具备更强的性能。在数据插入和更新时,能够自动路由和存储

支持存储大文件 :MongoDB 的单文档存储空间要求不超过 16MB。对于超过 16MB 的大文件,MongoDB 提供了 GridFS 来进行存储,通过 GridFS,可以将大型数据进行分块处理,然后将这些切分后的小文档保存在数据库中

相关推荐
不会写DN3 小时前
SQL 数据定义(DDL)全解
数据库·sql
linux修理工3 小时前
飞书机器人权限批量导入
服务器·数据库·asp.net
用户6279947182623 小时前
南大通用GBase 8a之基于散列点集合获取最小覆盖圆的方法
数据库
有想法的py工程师3 小时前
PostgreSQL 性能优化实战:一条 Order by 的 SQL 从 5 秒优化到 100ms
大数据·数据库·postgresql·性能优化
captain3763 小时前
数据库设计
数据库
XDHCOM1 天前
ORA-32484重复列名错误,ORACLE数据库CYCLE子句故障修复与远程处理方案
数据库·oracle
翻斗包菜1 天前
PostgreSQL 日常维护完全指南:从基础操作到高级运维
运维·数据库·postgresql
呆瑜nuage1 天前
MySQL表约束详解:8大核心约束实战指南
数据库·mysql