DBMS 的演进
本篇我们回顾数据库的发展历程,看看关系型数据库、NoSQL、NewSQL 以及云上数据库分别是在什么背景下出现的。理解这些演进脉络,能够帮助我们在做数据建模和技术选型时少一些“工具崇拜”,多一些对业务约束、数据规模和一致性要求的判断。
数据库的发展历史
1960 年代:数据库的诞生
早在 1960 年代,IBM 为了支持阿波罗计划,开发了 IMS 来存储数据,引入了代码与数据分离的思想,让开发者可以专注于操作数据,无需关心这些操作的底层实现细节。在之后的 1970 年代,作为关系型数据库的先驱,IBM 的 System R 和加州大学的 INGRES 数据库诞生,后者被其他大学广泛使用并在之后被商业化。与此同时,Oracle 发布了其第一版的 DBMS。
IBM 研究院基于研发 System R 数据库的经验,在 20 世纪 90 年代发表了三篇论文:
ARIES: A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging:提出了一套基于 WAL 的通用事务恢复算法,使数据库在崩溃后可以安全地分析、重做和撤销事务,从而保证原子性和持久性,即 A 和 D。
ARIESIKVL: A Key-Value Locking Method for Concurrency Control of Multiaction Transactions Operating on B-Tree Indexes:提出键值粒度的锁管理机制,使事务在访问 B+Tree 等结构时能够实现高并发且避免冲突,从而确保隔离性。
ARIES/IM: An Efficient and High Concurrency Index Management Method Using Write-Ahead Logging:提出高并发索引管理方法,使 B+Tree 在分裂、合并和结构调整时依然可并发访问并支持 WAL,从而实现高性能的索引更新与恢复。
这三篇核心论文再加上 ARIES/NT、ARIES/LHS 等论文组成了完整的 ARIES 理论,奠定了现代数据库的理论基础,几乎所有主流关系型数据库的事务恢复实现都受到了 ARIES 设计思想的影响。
1980 年代:创新与开源
1980 年代,IBM 发布了 DB2 数据库,与此同时还有 Sybase、Informix 等商业产品进入市场,推动着关系型数据库的普及。
在 1980 年代末、1990 年代初,有一股面向对象数据库设计的浪潮,旨在克服关系型数据库和面向对象编程语言之间的不匹配。虽然此类数据库没有成为主流,但在此过程中的许多技术创新为后来 XML 数据存储、对象存储以及 NoSQL 文档数据库的设计奠定了基础。
到了 1990 年代,开源数据库项目兴起,当前最流行的 MySQL 和 PostgreSQL 数据库均在此期间诞生。
2000 年代:互联网推动数据库革新
到了 21 世纪,互联网迅猛发展,互联网应用对高并发和高可用的需求,让传统数据库成为瓶颈。虽然可以通过垂直扩展来解决,但这种方法存在局限性,并且从低配机器向高配机器迁移数据的成本也非常高。
为了克服这些限制,Google、eBay 等公司开始采用 middleware 中间件的方式,将多台机器上的单点数据库组合起来,通过 middleware 做代理,实现跨机器的操作,但这种方式对复杂的查询和事务支持有限,有时候开发者需要自己来维护数据处理逻辑。像 eBay 的 middleware 组件就要求开发者自己实现事务和复杂查询。
总的来看,在互联网带来的需求面前,关系型数据库面临三个问题:
高可用高性能问题:关系型数据库的核心是 ACID,其关注重点在事务一致性和数据正确性,而这通常需要额外的锁、日志和同步开销,与互联网应用面对的高并发、高可用、高性能需求存在张力。
数据量问题:与互联网应用一起而来的还有海量的数据,使用像 MySQL 这样的数据库存储海量数据是非常不明智的选择。
数据建模问题:关系型数据库的数据建模和互联网应用所需的数据模型往往并不匹配,有时候需要更灵活、适配的建模方案。
以上问题最终催生了 NoSQL 数据库的诞生。
NoSQL 的崛起
NoSQL 指的是 Not Only SQL,是对非关系型数据存储服务的统称,包括键值存储、文档存储、列族存储、图数据库等。其最大的特点不是“不要 SQL”,而是围绕特定访问模式重构数据模型,在很多场景下放弃完整的 ACID 事务,转而追求高可用、可扩展和最终一致性。
Google 的 Bigtable、Amazon 的 Dynamo,以及后来的 Cassandra、MongoDB、Elasticsearch、Redis 等产品都可以归类到广义的 NoSQL 生态中。这类数据库通常以高可用分布式集群的形式存在,天然支持数据分片和多副本存储。部分写入密集型系统会采用 LSM-Tree 而不是 B+Tree 作为核心存储结构,从而提升顺序写入能力。
NewSQL 的诞生
NoSQL 数据库虽然解决了传统关系型数据库的很多问题,但同时也带来了新的问题。许多企业应用,尤其是金融、交易、订单、库存等场景,仍然要求强一致性和事务语义,同时又希望获得类似 NoSQL 的高性能、高可用和可扩展性。于是,试图同时提供 SQL、ACID 事务和水平扩展能力的数据库应运而生,此类数据库通常被称为 NewSQL 数据库。
They are a class of modern relational DBMSs that seek to provide the same scalable performance of NoSQL for OLTP read-write workloads while still maintaining ACID guarantees for transactions.
它们是一类现代关系型 DBMS,旨在为 OLTP 读写工作负载提供与 NoSQL 相同的可扩展性能,同时仍然为事务保持 ACID 保证。 《What’s Really New with NewSQL?》
NewSQL 大致分为三类:
全新架构的数据库
以 Spanner 为代表,采用全新架构设计、从零开发的数据库。这类数据库基本都采用分布式架构,支持跨节点并发控制和基于副本的容错处理。
大多数情况下,这类数据库不会依赖现成的存储系统或存储引擎,比如 HDFS、Apache Ignite,而是自己实现数据的分布式存储。这样做的好处在于可以让数据库 send the query to the data rather than bring the data to the query,在处理数据量巨大的场景时,可以极大的减少网络流量,提高吞吐性能。
通过自己管理数据存储,数据库还可以实现更加复杂、灵活的副本机制,比如 Aurora 实现的 3 可用区 6 副本的存储形式,这是许多直接依赖通用存储系统的数据库较难做到的。
这类采用新架构的 NewSQL 数据库的问题在于,架构复杂度和运维门槛更高,生态工具也可能不如传统数据库成熟。如果遇到问题,定位和治理成本往往更高。因此很多 NewSQL 产品都会尽量兼容已有数据库协议或 SQL 方言,降低业务迁移成本。
像 Google 的 Spanner,以及国内常见的 TiDB、OceanBase 都属于此类。
2. 透明中间件
另一种形式的 NewSQL 与之前的 middleware 思路类似,各个 DBMS 独立部署在多个节点上,然后通过一个中心化的 middleware 组件来管理数据的路由、查询、复制、事务处理等操作。通常在每个数据节点上,还会有一个 shim 程序作为代理与 DBMS 交互,执行具体的查询返回等操作。整个架构和现在的 Service Mesh 有些类似,通过 middleware、shim 组件的配合,让整个集群作为一个逻辑数据库对外提供服务。
该类型 NewSQL 数据库的最大优势在于可以直接替代当前数据库,应用层往往不需要大规模改造。但问题在于各个节点运行的依然是传统 DBMS,比如 MySQL、PostgreSQL 等,底层引擎的事务、锁、存储结构并没有本质变化。因此它更适合解决分片、路由、读写分离等工程问题,对于跨分片事务和复杂查询的支持通常有限。
AgilData Scalable Cluster2, MariaDB MaxScale, ScaleArc, ScaleBase3 等都属于此类 NewSQL。
3. 云上数据库
最后一种是云厂商以云服务形式提供的新架构数据库,典型代表是 AWS Aurora。对于此类数据库,用户不需要自己维护复杂的存储复制和故障切换机制,可以按需伸缩和付费。需要明确的是,并不是所有云上的关系型数据库都属于 NewSQL:如果只是托管传统数据库实例,本质仍然是数据库运维服务;只有采用新架构,同时支持 ACID、高可用、高性能和可扩展能力的数据库,才更接近 NewSQL 的讨论范围。国内阿里云的 PolarDB 也可以归类到这一类。
回顾这段历史可以发现,数据库的演进并不是从“旧技术”到“新技术”的简单替换,而是在不同约束下不断重新分配复杂度:关系型数据库把复杂度放在事务和查询优化器里,NoSQL 把复杂度更多交给数据模型和应用侧,NewSQL 则试图用分布式协议、时间戳、复制和调度系统重新托住 SQL 与 ACID。做数据建模时,我们真正要判断的是:这份复杂度应该由数据库承担,还是由业务系统承担。