目录

📄文档数据库 MongoDB 原理浅析

参考资料:https://zhuanlan.zhihu.com/p/87722764

简介

MongoDB 是最受欢迎的 NoSQL 数据库,文档数据库排名第一位,在所有数据库引擎中排名第五位(Oracle、MySQL、Microsoft-SQL-Server、Postgre SQL)。

了解 MongoDB 的发展历史可以查看 这篇文章

特性

以下是 MongoDB 的一些特性:

  • 面向文档存储,基于 JSON/BSON 可表示灵活的数据结构。因此与 javascript 有天生的兼容性,nodejs 服务则倾向于使用 mongodb 作为其底层数据结构;

  • 动态 DDL 能力,没有强 Schema 约束,支持快速迭代。同样也于 javascript 脚本语言的变量无类型性吻合。

  • 高性能计算,提供基于内存的快速数据查询;

  • 容易扩展,利用数据分片可以支持海量数据存储;

  • 丰富的功能集,支持二级索引、强大的聚合管道功能,为开发者量身定做的功能,如数据自动老化、固定集合等等。

  • 跨平台版本、支持多语言SDK。

基本模型

基本概念与操作

MongoDB 是最像关系型数据库的文档型数据库,为了实现关系型数据库的一些模型,MongoDB 自己定义了一些概念。

RDBMS 概念MongoDB 概念
databasedatabase。与 RDB 相同,表示表的集合。
tablecollection:一个 collection 可以存放多个文档。
不同之处在于 collectionschema 是动态的,不需要预先声明一个严格的表结构。更重要的是,默认情况下 MongoDB 并不会对写入的数据做任何schema 的校验。
rowdocument:相当于 RDB 中的“行”,一个文档由多个字段(列)组成,并采用bson 格式表示(下面阐述)。
columnfield:相当于 RDB 中的“列”,相比普通column的差别在于field的类型可以更加灵活,比如支持嵌套的文档、数组。
viewview:在 MongoDB3.4 之后实现了与关系型数据库基本相同的视图功能。它既可以是虚拟的,也可以是物理的视图。

对于字段,关系型数据库中有一些特殊类型的字段,它们在 MongoDB 中的映射关系如下:

RDBMS 字段MongoDB 字段
主键_id:MongoDB 用一种统一的分布式算法来实现这个字段的唯一性。
外键refrence:不同的是 MongoDB 并没有实现任何的约束检查功能。
索引index:与关系型数据库中索引的作用相同。后文详细阐述。

对于 SQL 中的一些操作,在 MongoDB 的 API 中也有类似的方法实现:

SQL 操作MongoDB 操作
join$lookup:一个聚合操作符,可以实现类似 SQL-Join 的功能
trransactionMongoDB 4.0 开始支持事务的支持
group byaggregation:MongoDB 通过 aggregation 提供的了强大的聚合计算框架。

PS:MongoDB 使用 SQL 进行查询需要借助第三方工具如 mongoboosterstudio3t

数据类型与主键

Bson 数据类型:

  • MongDB 的文档(即 SQL 中的行)可以使用 Js 的对象表示,从格式上讲是一种基于 Json 的叫 Bson(Binary Json) 的格式。

  • Bson 可以被认为是一种 Json 的扩展结构,它支持出了 Json 支持的基本数据类型之外的日期、正则表达式等类型。

分布式 ID:

  • 分布式 ID 算法是为了保证分布式数据的唯一性而诞生的一种算法。其中最有名的是 Twitter 研发的 snowflake 雪花算法,它同时使用“时间戳”、“机器号”、“进程号”、“随机数”来实现唯一性。
  • 而 MongoDB 的分布式 ID 算法则将随机数一部分替换为了初始化随机的自增 counter

索引

索引是一个数据库的关键能力,它的技术实现依赖于底层的存储引擎,MongoDB 使用 wiredTiger 作为默认的存储引擎。

MongoDB 的索引在实现上使用了 B+ 树的结构,这与其他的传统数据库没有什么区别。

评估与调优:

  • 使用 explain 方法可以用于对查询计划进行分析并且进一步评估索引的结果。进一步了解可以参考这篇文档

分布式集群

在讨论一个分布式集群时,通常通过描述以下这些方案的实现来讨论:“数据分片”、“数据备份”、“服务检测”等。

数据分片

将键空间根据一定的算法分布到不同的分布式节点上存储的方法,称为数据分片。而 MongoDB 支持两种分片方式:

  • “范围分片”、“哈希分片”。

由于考虑到在分布式系统中经常出现的单点故障或者出现新增加服务器,使用一致性哈希算法是更合理的解决方案:

  • 一致性哈希算法一般满足四个条件:“平衡性”(所有提供可用的服务管理的键值空间是大致相等的)、“单调性”(如果有新的服务加入系统,所有需要发生变更的数据都是变更到新的缓冲区)、“分散性”、“负载”、“平滑性”;

  • 分布式系统的一致性哈希算法最早在论文《Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web》中提出。

为了保证数据在各个服务器上复杂的均衡性:

  • MongoDB 提供了 “全预分配”、“非预分配” 两种方案;
  • 当使用后者策略时,不均衡状态会通过集群均衡器进行检测,一旦发现了不均衡则会执行数据迁移达到均衡;
  • 上面的数据迁移会对 MongoDB 集群的性能产生一定的影响,目前的规避手段只是将均衡窗口对齐到闲暇时段。

数据备份

通过与 Redis 类似的主从节点集实现,从节点从主节点备份数据。

当分布式系统检测到主节点宕机时,将会通过 Raft 算法选举出一个新的主节点进行升级。

数据检测

通过心跳链接检测分布式系统中单个主机的存活性。