SQL 与NoSQL 数据
关系 (SQL) 和非关系 (NoSQL) 是云原生应用程序中经常实现的两种数据库系统类型。 它们以不同的方式构建,以不同的方式存储数据,并以不同的方式访问。 在本部分中,我们将介绍这两类数据库。 本章稍后将介绍一种名为“NewSQL”的新兴数据库技术。
关系数据库是一项已经普及数十年的技术。 这种数据库成熟、经过验证且广泛实现。 相互竞争的数据库产品、工具和专业知识比比皆是。 关系数据库提供了大量相关数据表。 这些表具有固定架构,使用 SQL(结构化查询语言)来管理数据并支持 ACID 保证:原子性、一致性、隔离性和持续性。
No-SQL 数据库是指高性能的非关系数据存储。 它们具有出色的易用性、可伸缩性、复原能力和可用性。 NoSQL 不是联接规范化数据的表,而是存储非结构化或半结构化数据,通常存储在键值对或 JSON 文档中。 No-SQL 数据库通常不会提供超出单一数据库分区范围的 ACID 保证。 需要亚秒级响应时间的高容量服务倾向于使用 NoSQL 数据存储。
NoSQL 技术对于分布式云原生系统的影响怎么强调都不为过。 新数据技术在这一领域的激增扰乱了曾经完全依赖关系数据库的解决方案。
NoSQL 数据库包含用于访问和管理数据的多个不同模型,其中每个模型都适用于特定用例。 图 5-9 显示了四个常见模型。
图 5-9:NoSQL 数据库的数据模型
型号 | 特征 |
---|---|
文档存储 | 数据和元数据以分层形式存储在数据库中基于 JSON 的文档中。 |
键值存储 | 最简单的 NoSQL 数据库,数据表示为键值对的集合。 |
Wide-Column 存储 | 相关数据以一组嵌套键/值对的形式存储在单个列中。 |
图形存储 | 数据作为节点、边缘和数据属性存储在图形结构中。 |
CAP 定理
要了解这两种类型的数据库之间的差异,请考虑使用 CAP 定理,这组原则适用于存储状态的分布式系统。 图 5-10 显示了 CAP 定理的三个属性。
图 5-10。 CAP 定理
该定理指出,分布式数据系统会在一致性、可用性和分区容错之间做出权衡。 而且,任何数据库只能保证三个属性中的两个:
一致性。 群集中的每个节点都会使用最新数据进行响应,即使系统必须阻止请求直到所有副本都更新也是如此。 如果向“一致性系统”查询当前正在更新的项,将等待该响应,直到所有副本都成功更新。 不过,你将收到最新的数据。 在 CAP 定理上下文中使用的术语“一致性”应理解为具有技术意义,这与在 ACID 保证上下文中定义“一致性”的方式不同。
可用性。 系统中非故障节点收到的每个请求都必须产生响应。 简而言之,如果向“可用系统”查询正在更新的项,将获得服务此时可以提供的最佳回答。 但请注意,CAP 定理定义的“可用性”不同于技术上的“高可用性”,因为它通常以分布式系统而闻名。
分区容错。 保证系统继续运行,即使复制的数据节点发生故障或者与其他复制的数据节点的连接断开。
CAP 定理解释了在网络分区期间与管理一致性和可用性有关的权衡;但是,在缺少网络分区的情况下,也存在与一致性和性能有关的权衡。 CAP 定理通常会进一步扩展到 PACELC,以便更全面地解释权衡。
注意
即使你选择可用性与一致性,在网络分区的时,可用性也会受到影响。 CAP 可用系统更适用于某些客户端,但它不一定对所有客户端都“高度可用”。
关系数据库通常会提供一致性和可用性,但不提供分区容错。 它们通常会预配到单台服务器,并通过将更多资源添加到计算机进行垂直缩放。
许多关系数据库系统都支持内置复制功能,在这种情况下,可以将主数据库的副本创建到其他辅助服务器实例。 对主实例进行写入操作,并将其复制到每个辅助数据库。 发生故障时,主实例可以故障转移到辅助数据库,以提供高可用性。 辅助数据库也可以用于分发读取操作。 尽管写入操作始终针对主副本进行,但读取操作可路由到任何辅助副本以减轻系统负荷。
数据还可以在多个节点之间水平分区,例如通过分片。 但是,分片通过在多个无法轻松通信的部分中拆分数据,会显著增加运营开销, 而且这种方法的管理成本高昂且非常耗时。 包含表联接、事务和引用完整性的关系功能会在分片部署中导致较大的性能损失。
可以通过配置是以同步还是异步方式进行复制,优化复制一致性和恢复点目标。 如果数据副本在“高度一致”或同步关系数据库群集中失去网络连接,则你将无法向数据库写入。 系统将拒绝写入操作,因为它无法将更改复制到其他数据副本。 必须先更新每个数据副本,然后才能完成该事务。
NoSQL 数据库通常支持高可用性和分区容错。 它们通常跨商用服务器水平横向扩展。 此方法可在地理区域内和跨地理区域提供巨大的可用性,同时降低成本。 你可以在这些计算机或节点上对数据进行分区和复制,提供冗余和容错能力。 一致性通常通过一致协议或仲裁机制进行优化。 当在关系系统中在优化同步复制与异步复制之间做出权衡时,它们可以提供更多控制。
如果数据副本在“高度可用”的 NoSQL 数据库群集中失去连接,你仍然可以完成对数据库的写入操作。 数据库群集会允许写入操作,并在数据副本可用时更新每个数据副本。 支持多个可写副本的 NoSQL 数据库可以在优化恢复时间目标时避免故障转移,从而进一步增强了高可用性。
新式 NoSQL 数据库通常将分区功能作为其系统设计的一项功能来实现。 分区管理通常内置于数据库中,并通过放置提示(通常称为分区键)来实现。 灵活的数据模型使 NoSQL 数据库能够在部署需要数据模型更改的应用程序更新时降低架构管理的负担并提高可用性。
与关系表联接和引用完整性相比,高可用性和巨大的可伸缩性通常对业务更加重要。 开发人员可以通过多种方法和模式来实现最终一致性,如 Sagas、CQRS 和异步消息传递。
如今,在考虑 CAP 定理约束时必须小心谨慎。 一种新的数据库类型(称为 NewSQL)已经出现,它扩展了关系数据库引擎,以支持 NoSQL 系统的水平可扩展性和可缩放的性能。
关系系统与 NoSQL 系统的注意事项
基于具体的数据要求,基于云原生的微服务可以实现关系和/或 NoSQL 数据存储。
在以下情况下,请考虑 NoSQL 数据存储: | 在以下情况下,请考虑关系数据库: |
---|---|
有大量工作负荷需要可预测的大规模延迟(例如,每秒执行数百万个事务时以毫秒为单位的延迟时间) | 工作负荷量通常为每秒数千个事务 |
数据是动态的,并且经常更改 | 数据高度结构化,并且需要引用完整性 |
关系可以是反规范化的数据模型 | 关系通过规范化数据模型上的表联接来表达 |
数据检索简单明了,无需表联接即可表达 | 使用复杂的查询和报表 |
数据通常跨地理区域进行复制,并且需要更精细地控制一致性、可用性和性能 | 数据通常是集中式的,或者可以在区域之间异步复制 |
应用程序将部署到商用硬件上,如公有云 | 应用程序将部署到大型高端硬件上 |
在接下来的部分中,我们将探讨 Azure 云中提供的用于存储和管理云原生数据的选项。
数据库即服务
首先,可以预配 Azure 虚拟机,并为每个服务安装所选择的数据库。 尽管你对环境拥有完全的控制,但需要放弃云平台的许多内置功能。 你还要负责管理每个服务的虚拟机和数据库。 这种方法很快就会变得非常耗时和昂贵。
相反,云原生应用程序倾向于使用以数据库即服务 (DBaaS) 形式公开的数据服务。 这些服务由云供应商完全托管,提供内置的安全性、可伸缩性和监控。 你只需将其用作后备服务,而不是拥有该服务。 提供商大规模地运营资源,并负责性能和维护。
可以跨云可用性区域和区域对其进行配置,以实现高可用性。 它们都支持实时容量和即用即付模型。 Azure 具有不同类型的托管数据服务选项,每个选项都有特定的优点。
首先,我们将了解 Azure 中提供的关系 DBaaS 服务。 你将看到,Microsoft 的旗舰 SQL Server 数据库与多个开源选项一起提供。 接下来,我们将讨论 Azure 中的 NoSQL 数据服务。
Azure 关系数据库
对于需要关系数据的云原生微服务,Azure 提供了四个托管关系数据库即服务 (DBaaS) 产品/服务,如图 5-11 所示。
图 5-11。 Azure 中提供的托管关系数据库
在上图中,请注意每个数据库在一个通用 DBaaS 基础结构中的位置,该基础结构具有关键功能,且无需额外付费。
对于预配有大量数据库但管理这些数据库的资源有限的组织,这些功能尤其重要。 通过选择处理核心、内存和基础存储的数量,你可以在数分钟内预配 Azure 数据库。 你可以动态缩放数据库,并动态调整资源,而只需很少的停机时间。
Azure SQL 数据库
拥有 Microsoft SQL Server 专业技能的开发团队应考虑 Azure SQL 数据库。 这是一种基于 Microsoft SQL Server 数据库引擎的完全托管的关系数据库即服务 (DBaaS)。 该服务共享 SQL Server 本地版本中的许多功能,并运行 SQL Server 数据库引擎的最新稳定版本。
为了与云原生微服务一起使用,Azure SQL 数据库提供了三个部署选项:
单一数据库表示在 Azure 云中的 Azure SQL 数据库服务器上运行的完全托管 SQL 数据库。 该数据库被视为包含在内,因为它在基础数据库服务器上没有配置依赖项。
托管实例是 Microsoft SQL Server 数据库引擎的完全托管实例,提供与本地 SQL Server 近乎 100% 的兼容性。 此选项支持较大的数据库,最大可达 35 TB,并将其放在 Microsoft Azure 虚拟网络中,以便更好地进行隔离。
Azure SQL 数据库无服务器是单个数据库的计算层,可根据工作负荷需求自动缩放。 它仅对每秒使用的计算量进行计费。 该服务非常适用于具有间歇、不可预测的使用模式并夹杂着非活动状态的的工作负荷。 无服务器计算层还会在非活动期间自动暂停数据库,以便只对存储费用进行计费。 当重返活动状态时,它将自动恢复。
除了传统的 Microsoft SQL Server 堆栈以外,Azure 还提供三个常用开源数据库的托管版本。
Azure 中的开放数据库
开源关系数据库已成为云原生应用程序的常见选择。 许多企业都倾向于使用商业数据库产品,尤其是为了节省成本。 许多开发团队喜欢其灵活性、以社区为后盾的开发以及工具和扩展生态系统。 开源数据库可以跨多个云提供商进行部署,有助于最大程度地减少“供应商锁定”问题。
开发人员可以轻松地在 Azure VM 上自行托管任何开源数据库。 尽管提供了完全的控制,但这种方法需要你来负责管理、监控和维护数据库和 VM。
但是,Microsoft 通过提供几个常用的开源数据库作为完全托管的 DBaaS 服务,继续致力于使 Azure 成为“开放平台”。
Azure Database for MySQL
MySQL 是一种开源关系数据库,是针对 LAMP 软件堆栈构建的应用程序的支柱。 这种数据库广泛用于读取繁重的工作负荷,许多大型组织(包括 Facebook、Twitter 和 YouTube)都在使用它。 社区版免费提供,而企业版需要购买许可证。 该产品最初于 1995 年开发,2008 年被 Sun Microsystems 收购。 2010 年 Oracle 收购了 Sun 和 MySQL。
Azure Database for MySQL 是一个基于开源 MySQL Server 引擎的托管关系数据库服务。 它使用 MySQL 社区版本。 Azure MySQL 服务器是该服务的管理点。 它是用于本地部署的同一 MySQL 服务器引擎。 该引擎可以为每个服务器创建一个数据库,也可以为每个共享资源的服务器创建多个数据库。 你可以使用相同的开源工具继续管理数据,而不必学习新技能或管理虚拟机。
Azure Database for MariaDB
MariaDB 服务器是另一个常用的开源数据库服务器。 当 Oracle 购买 Sun Microsystems(拥有 MySQL)时,它是 MySQL 的一个分支。 目的是确保 MariaDB 保持开源。 由于 MariaDB 是 MySQL 的分支,因此数据和表定义是相互兼容的,客户端协议、结构和 API 是密切相关的。
MariaDB 具有强大的社区,许多大型企业都在使用。 尽管 Oracle 继续维护、增强和支持 MySQL,但 MariaDB Foundation 负责管理 MariaDB,允许对产品和文档进行公开贡献。
Azure Database for MariaDB 是 Azure 云中完全托管的一个关系数据库即服务。 此服务基于 MariaDB 社区版服务器引擎。 它可以处理具有可预测性能和动态可伸缩性的任务关键型工作负荷。
Azure Database for PostgreSQL
PostgreSQL 是一种开源关系数据库,持续开发超过 30 年。 PostgreSQL 在可靠性和数据完整性方面拥有良好的声誉。 它的功能丰富、符合 SQL 标准并且被认为具有比 MySQL 更高的性能,尤其适用于具有复杂查询和繁重写入的工作负载。 许多大型企业(包括 Apple、Red Hat 和 Fujitsu)都使用 PostgreSQL 构建过产品。
Azure Database for PostgreSQL 是一个基于开源 Postgres 数据库引擎的完全托管的关系数据库服务。 该服务支持许多开发平台,包括 C++、Java、Python、Node、C# 和 PHP。 可以使用命令行接口工具或 Azure 数据迁移服务将 PostgreSQL 数据库迁移到该服务。
Azure Database for PostgreSQL 提供了两个部署选项:
单服务器部署选项是多个数据库的中心管理点,你可以将多个数据库部署到这里。 定价是根据内核和存储按服务器来确定的。
超大规模 (Citus) 选项由 Citus Data 技术提供支持。 它通过水平缩放数百个节点上的单个数据库来实现高性能,从而提供更快的性能和规模。 此选项允许引擎在内存中容纳更多数据、跨数百个节点进行并行化查询,并更快地为数据编制索引。
Azure 中的 NoSQL 数据
Cosmos DB 是 Azure 云中完全托管的一个全球分布式 NoSQL 数据库服务。 它已由世界各地的许多大型公司采用,包括 Coca-Cola、Skype、ExxonMobil 和 Liberty Mutual。
如果你的服务需要从世界上的任何地方快速响应并提供高可用性或弹性可伸缩性,则 Cosmos DB 是一个不错的选择。 图 5-12 显示了 Cosmos DB。
图 5-12:Azure Cosmos DB 概述
上图显示了 Cosmos DB 中提供的许多内置云原生功能。 在本部分中,我们将详细介绍这些功能。
全球支持
云原生应用程序通常具有全球性受众,并需要全球规模。
你可以在各个区域或世界各地分布 Cosmos 数据库,将数据放置到用户附近,缩短响应时间并减少延迟。 无需暂停或重新部署服务,即可在区域中添加或删除数据库。 在后台,Cosmos DB 以透明方式将数据复制到每个已配置的区域。
Cosmos DB 支持全球级别的主动/主动群集,使你能够配置任何一个数据库区域来支持写入和读取。
多区域写入协议是 Cosmos DB 中的一项重要功能,可实现以下功能:
无限弹性写入和读取可伸缩性。
在全球 99.999% 的读写可用性。
在 99% 的时间内,在 10 毫秒内为读写提供服务。
利用 Cosmos DB 多归属 API,微服务会自动识别最近的 Azure 区域并向其发送请求。 最近的区域由 Cosmos DB 标识,无需进行任何配置更改。 如果某个区域不可用,多归属功能会自动将请求路由到下一个最近的可用区域。
多模型支持
将整体式应用程序重新平台化为云原生体系结构时,开发团队有时必须迁移开源 NoSQL 数据存储。 Cosmos DB 可通过多模型数据平台来保护在这些 NoSQL 数据存储中的投资。 下表显示了支持的 NoSQL 兼容性 API。
提供程序 | 说明 |
---|---|
NoSQL API | API for NoSQL 以文档格式存储数据 |
Mongo DB API | 支持 Mongo DB API 和 JSON 文档 |
Gremlin API | 支持具有基于图形的节点和边缘数据表示形式的 Gremlin API |
Cassandra API | 支持用于宽列数据表示形式的 Casandra API |
表 API | 支持具有高级增强功能的 Azure 表存储 |
PostgreSQL API | 用于以任何规模运行 PostgreSQL 的托管服务 |
开发团队只需对数据或代码进行最少的更改,即可将现有的 Mongo、Gremlin 或 Cassandra 数据库迁移到 Cosmos DB。 对于新应用,开发团队可以在开源选项或内置 SQL API 模型中进行选择。
在内部,Cosmos 以由基元数据类型构成的简单结构格式存储数据。 对于每个请求,数据库引擎将基元数据转换为所选择的模型表示形式。
在上表中,请注意表 API 选项。 此 API 是 Azure 表存储的进化形式。 两者共享相同的基础表模型,但 Cosmos DB 表 API 添加了 Azure 存储 API 中所没有的高级增强功能。 下表对这些功能进行了对比。
Feature | Azure 表存储 | Azure Cosmos DB |
---|---|---|
延迟 | 快速 | 在全球任意位置读取和写入的个位数毫秒级延迟 |
吞吐量 | 每个表 20,000 个操作的限制 | 每个表操作数不受限制 |
全局分发 | 具有可选单一次要读取区域的单个区域 | 通过自动故障转移统包式分发到所有区域 |
索引 | 仅适用于分区键和行键属性 | 对所有属性自动编制索引 |
定价 | 针对冷工作负荷进行优化(吞吐量-存储比低) | 针对热工作负荷进行优化(吞吐量-存储比高) |
使用 Azure 表存储的微服务可以轻松迁移到 Cosmos DB 表 API。 不需更改代码。
可调整的一致性
在前面的“关系与 NoSQL”部分中,我们讨论了数据一致性的主题。 数据一致性是指数据的完整性。 具有分布式数据的云原生服务依赖于复制,必须在读取一致性、可用性和延迟之间做出基本的权衡。
大多数分布式数据库允许开发人员在两种一致性模型之间进行选择:强一致性和最终一致性。 强一致性是数据可编程性的黄金标准。 它保证查询将始终返回最新数据,即使系统必须引发延迟,等待更新在所有数据库副本之间复制。 而配置为最终一致性的数据库会立即返回数据,即使该数据不是最新的副本。 后一个选项可实现更高的可用性、更大的规模和更高的性能。
Azure Cosmos DB 提供了五个明确定义的一致性模型,如图 5-13 所示。
图 5-13:Cosmos DB 一致性级别
这些选项让你可以做出精确的选择,并针对数据的一致性、可用性和性能进行精细的权衡。 下表显示了这些级别。
一致性级别 | 描述 |
---|---|
最终 | 读取没有排序保证。 副本最终会聚合。 |
常数前缀 | 读取操作仍是最终的,但数据按写入顺序返回。 |
会话 | 保证可以读取在当前会话期间写入的任何数据。 这是默认一致性级别。 |
有限过期 | 按指定的间隔读取尾随写入。 |
强 | 保证读取返回项的最新提交版本。 客户端永远不会看到未提交的读取或部分读取。 |
在 9 球的比赛规则:Cosmos DB 一致性级别介绍一文中,Microsoft 项目经理 Jeremy Likness 对五种模型进行了详细的说明。
分区
Azure Cosmos DB 采用自动分区来缩放数据库,以满足云原生服务的性能需求。
通过创建数据库、容器和项来管理 Cosmos DB 数据中的数据。
容器位于 Cosmos DB 数据库内,用于表示与架构无关的项分组。 项是添加到容器的数据。 它们表示为文档、行、节点或边缘。 添加到容器的所有项都将自动编制索引。
若要对容器进行分区,项将被划分为称为“逻辑分区”的不同子集。 逻辑分区根据与容器中每个项相关联的分区键的值进行填充。 图 5-14 显示了两个容器,每个容器都有一个基于分区键值的逻辑分区。
图 5-14:Cosmos DB 数据库分区机制
请注意上图中每个项如何包括“city”或“airport”的分区键。 键用于确定项的逻辑分区。 具有城市代码的项将分配给左侧的容器,具有机场代码的项将分配给右侧的容器。 将分区键值与 ID 值进行组合可创建项的索引,该索引唯一标识该项。
在内部,Cosmos DB 自动管理逻辑分区在物理分区上的放置,以满足容器的可伸缩性和性能需求。 随着应用程序吞吐量和存储要求的增加,Azure Cosmos DB 会在更多服务器之间重新分发逻辑分区。 重新分发操作由 Cosmos DB 管理,无需中断或停机即可调用。
NewSQL 数据库
NewSQL 是一种新兴的数据库技术,它将 NoSQL 的分布式可伸缩性与关系数据库的 ACID 保证相结合。 NewSQL 数据库对于必须跨分布式环境处理大量数据且具有完全事务支持和 ACID 符合性的业务系统非常重要。 尽管 NoSQL 数据库可以提供大规模可伸缩性,但它不能保证数据一致性。 数据不一致所导致的间歇性问题可能会给开发团队带来负担。 开发人员必须在微服务代码中构造防范措施,以管理数据不一致所引起的问题。
Cloud Native Computing Foundation (CNCF) 具有多个 NewSQL 数据库项目。
Project | 特征 |
---|---|
CockroachDB | 可在全球范围内缩放的符合 ACID 标准的关系数据库。 将新节点添加到群集,CockroachDB 跨实例和地理位置处理数据均衡。 它会创建、管理和分发副本以确保可靠性。 它是开源的,可免费使用。 |
TiDB | 一个开源数据库,支持混合事务处理和分析处理 (HTAP) 工作负荷。 它与 MySQL 兼容,具有水平可伸缩性、强一致性和高可用性。 TiDB 充当 MySQL 服务器。 你可以继续使用现有的 MySQL 客户端库,而无需对应用程序进行大量代码更改。 |
YugabyteDB | 一个开源、高性能、分布式 SQL 数据库。 它支持低查询延迟、针对故障的复原能力和全球数据分布。 YugabyteDB 与 PostgreSQL 兼容,可处理横向扩展 RDBMS 和 Internet 规模的 OLTP 工作负载。 该产品还支持 NoSQL,并且与 Cassandra 兼容。 |
Vitess | Vitess 是一种数据库解决方案,用于部署、缩放和管理 MySQL 实例的大型群集。 它可以在公有云或私有云体系结构中运行。 Vitess 结合并扩展了许多重要的 MySQL 特性,并且支持垂直和水平分片。 Vitess 源自 YouTube,自 2011 年以来一直在提供所有 YouTube 数据库流量。 |
上图中的开源项目可从 Cloud Native Computing Foundation 获得。 其中三个产品/服务是完整的数据库产品,其中包括 .NET 支持。 另一个,也就是 Vitess,则是一个数据库群集系统,可水平缩放 MySQL 实例的大型群集。
NewSQL 数据库的关键设计目标是在 Kubernetes 本机工作,从而利用平台的复原能力和可伸缩性。
NewSQL 数据库设计为在临时云环境中发展,在这类环境中,可以立即重启或重新计划基础虚拟机。 这种数据库可在节点故障中幸存,不会丢失数据,也不会造成停机。 例如,CockroachDB 通过跨群集中的节点维护任何数据的三个一致副本,可在机器丢失时幸存。
Kubernetes 使用 Services 构造允许客户端从单个 DNS 条目处理一组相同的 NewSQL 数据库进程。 通过将数据库实例与其关联的服务的地址分离,我们可以进行缩放,而不会中断现有的应用程序实例。 在给定时间向任何服务发送请求将始终产生相同的结果。
在此情景中,所有数据库实例都是平等的。 不存在主要或辅助关系。 使用 CockroachDB 中的一致复制等方法,任何数据库节点都能够处理任何请求。 如果接收负载均衡请求的节点有本地所需的数据,则它会立即响应。 如果没有,节点将成为网关,将请求转发到相应的节点,以获得正确答案。 从客户端的角度来看,每个数据库节点都是相同的:它们都显示为具有单计算机系统的一致性保证的单一逻辑数据库,尽管有数十甚至数百个节点在后台工作。
有关 NewSQL 数据库背后的机制的详细信息,请参阅 DASH:Kubernetes 原生数据库的四大属性一文。
将数据迁移到云
更耗时的一项任务是将数据从一个数据平台迁移到另一个数据平台。 Azure 数据迁移服务可帮助加快此类工作。 它可以将数据从多个外部数据库源迁移到 Azure 数据平台,并尽量减少停机时间。 目标平台包括以下服务:
- Azure SQL 数据库
- Azure Database for MySQL
- Azure Database for MariaDB
- Azure Database for PostgreSQL
- Azure Cosmos DB
该服务提供建议,指导你完成执行迁移所需的更改(无论大小)。