背景
数据库的演进
随着计算机的发展,越来越多的数据需要被处理,数据库是为处理数据而产生。从概念上来说,数据库是指以一定的方式存储到一起,能为多个用户共享,具有更可能小的冗余,与应用程序彼此独立的数据集合。从功能上来说,就是数据管理软件。
自1960s数据库的概念被提出,到1970s IBM的Edgar Codd第一次提出关系型数据库的概念,再到1980s,传统的关系型数据库已经能满足大部分的日常数据存储的需求,Oracle、IBM等商业化数据库也得到了蓬勃的发展。这个阶段可以认为是关系型数据库的天下,Oracle是公认的老大哥!
到了2000年随着互联网的发展,数据量呈现爆发式增长。海量数据的诞生,传统的关系型数据库在应对大规模,超大流量的时候就显得力不从心。借此,NoSQL数据库,NewSQLl数据库就此登场。
NoSQL 全称 "not only sql",所有非关系型的数据库都统称为NoSQL数据库,NoSQL数据库主要有四种类型,文档数据库(MongoDB为代表),键值数据库(Redis为代表),宽列存储(Hbase为代表)和图形数据库(Neo4J为代表)。NoSQL抛弃了传统数据库强事务保证和关系模型,重点放在高可用,可扩展性和高性能上。不支持SQL。
NewSQL数据库,提供了与NoSQL相同的扩展性,但仍属于关系型模型,还保留SQL作为查询语言,保证了ACID事务性。代表数据库有Spanner,CockroachDB。
数据库发展到今天,可以说是百花齐放,随着2020年阿里云数据库进入全球魔力四象限的Leader象限,这也是中国数据库40年来首次进入全球顶级数据库行列,标志着国产数据库开始崛起。我也希望自己在中国数据库技术发展上贡献一份自己的力量。
在了解了数据库的发展后,我们再来看看对数据库来说哪些技术原理是不变的?这就要进入下文讲到的数据库索引技术了。
数据库索引技术
数据库是用来处理数据的,那高效的存储、检索数据,是数据库管理系统必备的技能。数据库中用于提高检索效率很重要的一项技术就是索引。讲到索引就不得不提下数据结构,我们来一起回顾下数据结构和算法的基础知识。
数据结构指的是“一组数据的存储结构”,算法指的是“操作数据的一组方法”。数据结构是为算法服务的,算法是要作用在特定的数据结构上的。数据库提高检索效率使用的是索引,数据库索引是一种树形数据结构,如MongoDB使用的是B-tree、MySQL使用的是B+tree。
什么是B树(B-Tree)
我们来看下B树,如下图这是一颗3阶B树的例子:
通过学习B树,我们知道B树有以下特点
- B树在查询中的比较是在内存中完成的,相比磁盘IO的速度,内存中的比较耗时几乎可以忽略。所以只要树的高度足够低,IO次数足够少,就可以提升查找性能。
- B树为了插入一个元素,多个节点发生了连锁改变,会有一定的性能损耗,但也正因为如此,B树能够始终维持多路平衡。这也是B树的另外一大优势:自平衡。
- 查找的元素在不同的结点(根结点、中间结点、叶子结点),性能会有一定差别,因此查询性能不稳定。
- 范围查找性能不高。
我们知道二叉查找树查询的时间复杂度是O(logN),查找速度最快和比较次数最少,既然性能已经如此优秀,但为什么实现索引是使用B-Tree而不是二叉查找树,关键因素是磁盘IO的次数。
磁盘读取依靠的是机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加就是一次磁盘IO的时间,大概9ms左右。这个成本是访问内存的十万倍左右。正是由于磁盘IO是非常昂贵的操作,所以数据库性能优化的核心思想是降低磁盘IO次数。
说明:
普通的机械盘HDD一次磁盘IO的时间大概是9ms
普通SSD一次磁盘IO耗时大概是0.2ms(IOPS:5000)
PCIe卡一次磁盘IO耗时大概是0.05ms(IOPS:20000)
从二叉树的查找过程了来看,最坏的情况下磁盘IO的次数由树的高度来决定。要减少磁盘IO的次数就必须要压缩树的高度,让瘦高的树尽量变成矮胖的树,所以B-Tree就在这样伟大的时代背景下诞生了。
在了解了数据库的发展及索引技术后,我们再进入今天的主题MongoDB,相信大家就有一定的体感了。
MongoDB介绍
本文重点介绍MongoDB,它虽然诞生于NoSQL,但4.0版本之后,已经不仅仅是NoSQL了,可以与上文中任何一位NewSQL的代表PK。MongoDB是一个开源、高性能、无模式的文档数据库,旨在简化开发和扩展。
MongoDB体系结构
副本集架构
默认情况下,客户端从Primary读取数据,但可以配置读取首选项将读取操作发送到Secodary
备注
MongoDB复制是异步的,若配置了从Secondary读取数据,则需要业务接受数据延迟。
分片集群架构
一个 MongoDB分片集群由以下组件组成:
- shard:每个分片包含分片数据的一个子集。每个分片都可以部署为副本集。
- mongos:
mongos
充当查询路由器,在客户端应用程序和分片集群之间提供接口。 - config servers:配置服务器存储集群