Skip to main content

数据基层简介

· 17 min read
EloqData

在这篇博客中,我们介绍我们的变革性概念数据基层。数据基层抽象了在线事务数据库(OLTP)中的核心功能,为任何数据模型的 CRUD 操作提供统一层。基于这个统一层构建的数据库是模块化的:数据库模块是可选的,可以替换,并且可以独立于其他模块进行扩展。

动机

在计算机发展的早期,数据存储在普通文件中并由自定义程序处理。关系型数据库管理系统(RDBMS)在 20 世纪 70 年代出现,将数据建模为表格,在磁盘上以一致性和完整性存储,并提供 SQL 来访问它们。RDBMS 在二十多年里一直是数据管理的事实标准解决方案。

但这在 2000 年代初期随着互联网的迅猛发展而改变。互联网应用程序,如搜索引擎、社交网络和电子商务网站,产生了大量数据并重新定义了数据密集型工作负载。"一刀切方案不适合所有情况"成为定义数据库系统未来几十年的口号。从那时起,数据库领域在两个方向上发展:可扩展性和数据模型。

让数据库具有可扩展性很难。在保持 ACID 属性并最小化性能影响的同时做到这一点更难。NoSQL 趋势,以 Google BigTable 和 Amazon Dynamo 为代表,因为用可扩展性换取 ACID 而闻名。NewSQL 和分布式 SQL 数据库,如 CockroachDB,后来重新引入了事务,但通常以效率为代价。最近,云原生数据库如 Amazon Aurora 通过解耦计算和存储来实现存储的可扩展性,避免了扩展事务这个更困难的任务。

第二个趋势是多样化的数据模型的出现。简单的键值对对于缓存目的来说已经足够,图形对于建模关系很重要,而流和时间序列对于建模持续变化的数据是理想的。关系模型无法很好地支持所有应用程序变得越来越清晰。随着多样化数据类型和结构的出现,为这些新数据模型开发的数据库也随之出现,同时还有新的查询语言。

过去二十多年的数据库演进导致了一个极其复杂的数据库格局。现在,我们有大量针对不同数据模型的数据库,进一步按规模(单节点、分布式存储、完全分布式)、环境(本地、云)和存储设备(内存、SSD、非易失性内存)分类。这种分散化给用户带来了巨大的挑战。正如 Andreessen Horowitz 的一篇文章所示,现代数据管道现在由众多专门组件组成,每个组件都设计用于处理特定任务,形成了一个用户必须导航的工具和系统迷宫。如果云提供商需要多篇文章决策图来解释如何选择正确的数据库,许多人会同意我们可能走得太远了

我们是否必须为每种新的数据模型/环境/硬件类型从头开始构建一个新的数据库?如果我们检查一个新数据库并将其与现有数据库进行比较,很明显大多数功能是相同的。新数据库必须重新实现许多之前已经开发过多次的功能才能提供一些新价值。我们应该,而且我们相信我们可以,做得更好。

在 EloqData,我们对这个宏大问题的答案是数据基层

灵感:单节点 RDBMS

数据基层的灵感来自单节点关系型数据库管理系统(RDBMS)的规范设计。要理解数据基层的起源,让我们回顾一下 RDBMS 的功能。简化来说,RDBMS 内核包含 4 个模块:(1) 一个用于存储数据项的磁盘驻留 B+ 树,(2) 一个用于持久化数据更改的预写日志,(3) 一个用于在内存中缓存 B+ 树页面的缓冲池,以及 (4) 一个用于协调并发控制的读写的锁表。

Data Substrate Architecture

考虑一个读取和更新数据项 x 的事务 T。T 遍历 B+ 树并在缓冲池中搜索每个页面(①)。如果发生缓存未命中,T 定位磁盘驻留页面(②)并将其加载到缓冲池中(③)。然后 T 在缓冲池中固定包含 x 的页面,在锁表中为 x 添加读锁(④),读取 x(⑤)并取消固定页面。

要更新 x,T 将 x 的锁升级为写锁(⑥),更新缓冲池中 x 的页面(⑦)并将重做/撤销操作追加到日志(⑧)。T 通过同步刷新提交记录到日志来提交,这也强制之前的重做/撤销日志条目持久化。

当 T 提交时,x 的更改记录在日志中和缓冲池中的内存页面中,但尚未记录在磁盘驻留的 B+ 树中。一个称为检查点的后台进程定期将脏页面刷新到磁盘(⑨)。

虽然最初是为表格数据的事务处理而设计,但这些设计原则对于支持 CRUD 操作是最优的。这个过程中最重要的四个支柱是:

  • 持久性。为确保数据持久性,系统使用追加式日志来持久化更改。顺序写入提供了从稳定存储可实现的最高写入吞吐量。在关键路径中只有一次同步写入,没有任何设计能提供更高的吞吐量和更低的延迟。日志对于数据安全也至关重要,因为大多数存储设备在断电期间无法避免部分写入。

  • 缓存。有了日志提供持久性,数据更改就保留在内存中。这减少了写入路径中的 IO,并防止后续操作读取到过时的数据。在内存中缓存也优化了未来读取的性能。

  • 异步性。缓存的数据更改异步刷新到稳定存储,这通过两种方式减少了写入稳定存储的成本。首先,对同一数据项的多次更改被合并。其次,可以累积一批更改并重组以优化顺序写入。

  • 一致性和容错。异步性在数据更改在缓存中可见和刷新到稳定存储之间创建了一个窗口。为了处理故障,系统维护一个不变量:数据更改必须存在于缓存、稳定存储或两者中。这个不变量确保 (1) 在缓存替换期间,除非已经刷新,否则不能驱逐脏页面,以及 (2) 在故障转移期间,未刷新的更改必须从日志恢复到缓存或稳定存储中。

数据基层

这些设计原则的价值超越了 RDBMS。无论数据项是表中的一行、一个数据结构还是一个 JSON 文档,只要我们想要安全地将其存储在稳定存储中,持久性原则就适用。无论数据库在单个节点上运行还是在分布式环境中,内存都是快速但稀缺的,存储是丰富但慢的,所以我们需要缓存和异步原则来平衡两者以服务读写操作。在数据基层中,我们将这些原则扩展到任何数据模型在分布式环境中的(非事务性)CRUD 操作。

  • 持久性。数据基层使用分布式、复制的日志来持久化数据更改。每个日志记录器都进行复制以实现高可用性。拥有多个日志记录器提供了写入吞吐量的可扩展性。

  • 缓存和并发控制。数据基层使用分布式、内存中的映射进行缓存和并发控制。我们称这个映射为"TxMap"。映射键标识一个数据项,有效负载包括值和用于并发控制的元数据。访问映射条目读取/写入缓存的值并执行并发控制。并发控制是可选的:如果操作是非事务性的或不需要锁,访问不会更改元数据。

Data Substrate Architecture 2

  • 异步性。更改的数据项首先刷新到日志,然后更新在 TxMap 中。更新的数据项异步刷新到持久存储。持久存储扮演与 B+ 树相同的角色,在稳定存储中存储数据项。持久存储暴露 Get()、Put() API 用于读取和写入数据项。

Data Substrate Architecture 3

  • 一致性和容错。数据基层维护与 RDBMS 相同的不变量:(1) 更改的数据项在从 TxMap 驱逐之前必须刷新到持久存储,以及 (2) TxMap 的故障转移节点在开始服务之前必须从日志中恢复未刷新的数据项到 TxMap 中。

Data Substrate Architecture 3

模块化

Data Substrate Architecture 4

数据基层的独特之处在于模块化。TxMap 暴露 API 供运行时访问数据和管理并发控制。持久存储暴露 API 供 TxMap 刷新更改的数据和检索已驱逐的数据。日志提供 API 用于持久化数据更改并将未刷新的数据发送到 TxMap 以进行恢复。模块通过精心设计的 API 相互通信,不假设其他模块的位置、实现方式或使用的硬件资源。

数据基层和持久存储对数据类型是不可知的。无论数据项代表一行还是一个 JSON 文档,并发控制和缓存替换算法都不会改变。日志条目包含序列化的数据项更改,这也与数据类型无关。持久存储通过标识符索引数据项,使用相同的索引结构。本质上,不同类型的数据面临相同的系统挑战,数据基层一次性解决它们。构建特定数据模型的操作数据库大大简化,只需在顶部放置特定的查询引擎即可。

模块化也改变了数据库的扩展方式。传统上,数据库要么垂直扩展,要么水平扩展。最近云原生数据库解耦计算和存储的趋势允许 CPU 和存储独立扩展。数据基层的模块化更进一步,以最细粒度扩展数据库:CPU、缓存(内存)、日志(存储)和持久存储(存储)。这种扩展灵活性允许数据库使用最少的资源满足应用程序的性能要求。

  • 对于读密集型、延迟敏感的应用(如社交网络信息流),数据库缓存热数据在内存中,只在工作负载激增时扩展缓存。如今,单个虚拟机的内存从 4 GB 到超过 256 GB。因此,扩展数据库缓存首先是垂直扩展,超过某个点后才水平扩展。日志规模很小,因为工作负载主要是读取。
  • 对于写密集型应用(如高频交易),数据库水平扩展日志到多个存储设备以快速持久化更改。水平扩展确保写入吞吐量高,同时保持写入延迟低。日志独立于缓存大小和数据量,后者可能很小并且适合单机内存和磁盘。

虽然我们相信 ACID 事务对应用程序至关重要,但我们也相信 ACID 事务应该是可选的,这样不需要它们的应用程序就不必付出代价。在数据基层中,这是通过禁用某些模块或绕过 ACID 事务逻辑来实现的。例如,通过禁用日志,数据库放弃持久性并成为缓存系统。

EloqKV 及其他

数据基层开启了许多机会。无论你是构建缓存、内存数据库,还是针对某个数据模型的云原生数据库,你只需在数据基层之上放置查询解析器和执行引擎,就万事俱备了。你获得了一个弹性、高性能和容错的操作数据库。

我们正在开发数据基层的第一个实例,一个键值数据库。你最喜欢的数据模型是什么?你最期待数据库具备哪些能力?给我们留言。我们会在下一代数据库取得进展时随时通知你。