本文档可帮助软件开发者和数据库管理员将现有 Aerospike 应用迁移到以 Bigtable 作为数据库的应用。它会利用您对 Aerospike 的了解来描述在迁移到 Bigtable 之前需要了解的概念。
为帮助您开始使用 Bigtable 和 Aerospike,本文档将执行以下操作:
- 比较 Aerospike 和 Bigtable 之间的术语。
- 概述了 Bigtable 操作,并介绍了 Bigtable 中的数据布局。
- 说明了数据建模和关键设计注意事项。
- 明确说明了如何实现复制以及复制的影响。
如需了解迁移流程以及可用于完成迁移的开源工具,请参阅从 Aerospike 迁移到 Bigtable。
术语比较
Aerospike 和 Bigtable 都是分布式 NoSQL 数据库,但在设计、操作和术语方面有很大不同。
在 Aerospike 中,数据存储在记录中。每条记录都包含一个或多个命名箱,以及记录大小(以字节为单位)、存留时间 (TTL) 和上次更新时间 (LUT) 等元数据。
Bigtable 将数据存储在可伸缩的表中,其中每个表都是有序的键值对映射。该表由行键索引的行和由列限定符标识的列组成。如果列彼此相关,则可以组成一个列族。借助此结构,您可以在同一键下存储多个版本的值。每个版本都由唯一的时间戳标识。在读取操作期间,可以根据配置的政策过滤掉早期版本,也可以通过垃圾回收功能移除早期版本。
如需了解详情,请参阅 Bigtable 存储模型。
下表概括说明了共享概念,并说明了每种产品使用的相应术语:
| Aerospike | Bigtable |
|---|---|
| 没有直接对应的项。 | 实例:一个受管理的集群组,位于不同的 Google Cloud 可用区或区域,在这些可用区或区域之间会发生复制和连接路由。 |
| 集群:Aerospike 部署由一组节点组成。 | 集群:一组位于同一地理位置的 Google Cloud 可用区中的节点。 |
| 节点:提供计算能力并拥有其存储空间的服务器。 | 节点:仅提供计算的服务器。存储由单独的分布式文件系统 Colossus 处理。 |
| 命名空间:存储 TTL 或存储类型等参数。在命名空间内,数据会细分为集合和记录。 | table:最接近 Aerospike 命名空间的等效项。某些参数是在集群级为所有表设置的。您可以在表级或列族级进行更精细的控制。 |
| set:用于对记录和参数(如 TTL 和上限大小)进行逻辑划分。键在集合中必须是唯一的。 | 没有直接对应的项。 |
| 没有直接对应的项。 | 表:一种实例级资源,会自动复制到每个集群。表包含一组由唯一行键标识的值。表是稀疏的,这意味着它们不会使用额外的空间来存储不包含任何值的列。 |
| 没有直接对应的项。 | 平板:一起存储的连续行范围。Bigtable 通过将片分配给节点来实现负载均衡。平板电脑边界是动态的,可以随时间推移而拆分或合并。 |
| 记录:用于存储数据的一组命名箱。大小不得超过 8 MB。 | 行:一组由列族、列限定符和时间戳标识的值。所有行级操作都属于原子操作。 |
| 没有直接对应的项。 | 列族:按字典顺序排序的一组列。垃圾回收是在此级别设置的。 |
| 箱:一种键值对,其中箱名称是记录中值的标识符。 | 列限定符:在表中存储的值的标签。 |
| 没有直接对应的项。 | 单元格:存储在表中的带时间戳的值的标签。 |
| (记录)摘要:用于标识记录的三元组(命名空间、集合和键)的哈希。 | 没有直接对应的项。 |
| key:记录标识符,在相应集合中必须是唯一的。 | 行键:行标识符,在表中具有唯一性。 |
| AQL:一种命令行工具,用于浏览数据和为 Aerospike 数据库开发用户定义的函数。 | GoogleSQL:一种由多种 Google Cloud 服务(包括 Spanner、BigQuery 和 Bigtable)使用的查询语言。 |
数据类型限制
下表比较了 Aerospike 和 Bigtable 使用的数据类型的限制:
| Aerospike | Bigtable |
|---|---|
| 命名空间: 企业版的命名空间数量上限为 32 个。 | 表:一个实例最多可以有 1,000 个表。表格名称不能超过 50 个字符。 |
| set:一个集群最多可以有 4,095 个集合。集合名称不能超过 63 个字节。 | 没有直接对应的项。 |
| 录制:录制内容的大小上限为 8 MB。 | 行:最大行大小为 256 MB。 |
| 没有直接对应的项。 | 列族:列族数量不受限制,但超过 100 个可能会导致性能下降。 |
| 箱:箱的数量不受限制,但每个箱最多可容纳 1 MB 的数据。箱柜名称不能超过 15 个字节。 | 列限定符:上限为 100 MB,但建议不要超过 10 MB。列数不受限制。 |
| 键:键大小上限为 8 KB。 | 行键:行键大小上限为 4 KB。 |
如需详细了解 Bigtable 和 Aerospike 限制,请分别参阅配额和限制以及 Aerospike 系统限制和阈值。
架构
以下部分简要介绍了 Bigtable 和 Aerospike 的架构。
Bigtable
Bigtable 节点与存储层是分开的,这意味着节点不会影响数据持久性。Bigtable 表客户端不知道底层数据分布。额外的路由层会将请求分发到正确的节点。每个节点会处理对集群的一部分请求。Bigtable 表被分成多个连续的行块(称为“片”),这些片存储在 Colossus 上,Colossus 是一种可提供高耐用性的分布式文件系统。每个 tablet 都与特定的 Bigtable 节点相关联。
Bigtable 的架构具有以下优势:
- Bigtable 客户端无需了解数据分布和负载均衡。此类复杂性由路由层处理。
- 再平衡速度非常快,并且从故障中恢复的速度也很快,因为实际数据不会在节点之间复制。
- 当 Bigtable 节点发生故障时,任何数据都不会丢失。
Aerospike
与 Bigtable 不同,Aerospike 的存储位于提供服务的节点上。Aerospike 集群中的每个节点(服务器)都相同。每个命名空间中的数据都会通过对记录名称进行哈希处理,划分为 4,096 个分区。这些分区均匀分布在各个节点之间。
节点彼此感知,并在集群发生变化时重新平衡存储的分区。每次发生集群更改时,副本都会选举一个主副本来协调重新平衡。客户端库应跟踪哪个副本存储了主分区,并将写入请求发送到正确的副本。如果客户端向错误的节点发送请求(这可能会在重新平衡期间发生),则节点会重新路由该请求。
复制
本部分比较了 Aerospike 和 Bigtable 的复制流程。
Bigtable
一个 Bigtable 实例可以包含单个集群或多个复制的集群。表始终会复制到实例中的所有集群。您可以在某个实例中添加和移除集群,这对其他集群几乎没有影响。
Bigtable 在单个集群内提供读己所写 (read-your-writes) 一致性。写入在单个集群上执行,并且在实例中的其他集群中最终保持一致。与 Aerospike 不同,Bigtable 不会丢失中间更新,因为各个单元格在内部进行了版本控制,确保不会丢失任何写入。每个集群都会提供具有可用最新时间戳的单元格。
Bigtable API 提供表级一致性令牌,可用于验证在创建令牌之前所做的所有更改是否已完全复制。
Aerospike
Aerospike 在分区级别处理集群内的复制。命名空间会拆分为多个分区,这些分区会均匀分布在各个节点之间。在集群内,系统可确保强一致性。只有在集群中的所有副本都确认写入操作后,系统才会确认该写入操作。
您可以配置跨数据中心复制 (XDR),以实现不同集群之间的数据同步。Aerospike 的 bin 收敛可确保在复制结束时,所有数据中心的数据最终相同,但中间更新可能会丢失。
为了实现持久性,Aerospike 基于名册的一致性算法需要 N+1 个副本才能处理 N 个故障。
数据模型
本部分比较了 Bigtable 和 Aerospike 使用的数据模型。
灵活的架构
Aerospike 不强制执行架构限制,允许每条记录具有不同的箱,且箱的值类型各不相同。同样,Bigtable 支持稀疏列,因此没有值的列不会占用任何存储空间。虽然列或列族的数量没有严格限制,但出于性能方面的考虑,最好将列族的数量控制在 100 个以内。
行键设计
Bigtable 通过行键来标识行,行键在表中必须是唯一的。它们按字典顺序排序,并一起保存在平板电脑中。这与 Aerospike 不同,在 Aerospike 中,记录会根据其哈希值分布在各个节点中。行键的设计应确保经常一起访问的行也存储在一起。
数据类型
Aerospike 支持高级数据类型,包括标量、GeoJSON、HyperLogLog、列表和嵌套对象。这些类型可以通过二级索引进行索引和查询。此外,Aerospike 还提供服务器端 API,可对这些数据类型执行复杂操作,例如按地理位置过滤或操纵列表内容。
Bigtable API 主要侧重于处理原始字节,但也有一些例外情况。它还原生使用 INT64 来表示时间戳和计数器,这些时间戳和计数器可以作为原子操作递增。查询语言还支持许多复杂类型,例如标量、JSON 对象和 HLL 箱。未来可能会越来越支持高级类型,但在撰写本文档时,无法将此类类型放入 Bigtable 中,所有内容都在客户端序列化。您可以使用 aerospike-migration-tools 中的适配器库来序列化数据类型。
列族
在 Bigtable 中,列族用于定义表中哪些列一起存储和检索,并且每个表都必须至少包含一个列族。相关列应归入同一列族。由于垃圾回收政策是在列族级应用的,因此应将具有不同保留要求的数据分别放入不同的列族中。
列限定符
在 Bigtable 中,列限定符用于在列族内定义各个列。表可以支持数百万列,但最佳实践是限制单行中的列数。(可选)列限定符可以视为数据,从而允许将值直接嵌入列名称中以节省空间。
Cells
在 Bigtable 中,单元格是行键和列名称(列族与列限定符组合)的交集。每个单元格都包含一个或多个由时间戳提供的值,该值可以由客户端提供或由服务自动应用。
二级索引
连续的物化视图可以充当异步二级索引,使表能够使用不同的查找模式或属性进行查询。如需了解详情,请参阅创建异步二级索引。
交易
Bigtable 和 Aerospike 都不支持多行事务,但在单行功能方面有所不同。Bigtable 支持在集群内实现完全一致的单行写入,并通过 mutate-row 请求支持单行事务。它们允许对单行执行多项操作,所有操作都以原子方式执行,要么全部成功,要么全部失败。此外,还有读取-修改-写入和检查并更改操作,不过这些操作不适用于多集群路由配置文件。相比之下,Aerospike 通过服务器端数据操作和执行客户端定义的功能来扩展单行事务。
负载均衡和故障切换
Aerospike 使用智能客户端在客户端处理负载均衡。在客户端运行的进程,可感知集群状态和数据分布。此客户端负责路由请求。
如果某个节点发生故障或添加了新节点,则必须重新平衡集群。系统会选择一个临时主节点来协调节点之间分区重新平衡和重新分配的操作。在此期间,集群会保持运行状态,但客户端必须跟踪更改以进行请求路由。如果请求到达了错误的节点,系统会将其内部路由到正确的节点。
Bigtable 客户端是一个精简客户端,可向用户隐藏所有复杂性,例如集群状态和数据分布。请求的路由由下一层(即 Google CloudBigtable 基础架构中的胖客户端)处理。
另一个区别是 Aerospike 中没有的路由政策。Bigtable 使用应用配置文件来管理请求路由,并提供可配置的优先级来控制请求的服务顺序。路由政策分为两种类型:单集群和多集群。多集群配置文件将操作路由到距离最近的可用集群。从操作路由器的角度,同一区域中的集群被视为等距离。如果负责所请求键范围的节点在集群中过载或暂时不可用,此配置文件可以提供自动故障切换。相比之下,如果整个集群发生故障,Aerospike 不会提供自动故障切换。
备份和恢复
Aerospike 提供名为 asbackup 和 asrestore 的外部备份和恢复工具,这些工具可在客户端创建逻辑备份,类似于执行扫描。备份管理还可以通过 Aerospike Backup Service 或 Aerospike Kubernetes Operator 来处理,这两者都在内部使用 asbackup 和 asrestore,并提供调度和多进程协调功能。备份不是原子性的,这意味着备份期间发生的写入操作可能不会被捕获。
Bigtable 提供了两种方法来满足常见的备份需求:Bigtable 备份和托管式数据导出。备份会创建存储为集群成员对象的表的可恢复副本。您可以将备份作为启动备份的集群中的新表进行恢复。如果发生应用级别损坏,则备份旨在创建恢复点。Bigtable 备份也不是原子性的。可能会在备份已复制的表部分中进行更改。
备份处理方面的主要差异
- Aerospike 备份是在客户端创建的。它们不需要任何额外的服务器端空间,但速度较慢。在 Bigtable 中,备份会与源表和该表的其他备份共享物理存储空间。
- Aerospike 的用户需要负责导出、存储和移除过时的备份。由于 Bigtable 中的备份是完全集成的,因此 Bigtable 服务会自动处理所有这些操作。
性能考虑因素
由于 Aerospike 和 Bigtable 对读取和写入操作的处理方式不同,因此它们在性能方面存在差异,这一点非常重要,需要加以考虑。下表列出了这两个数据库之间的一些性能差异示例。如需了解详情,请参阅 Bigtable 性能指南。
| 考虑因素 | Bigtable | Aerospike |
|---|---|---|
| 热门行 | 分配 tablet 和操作,以均衡资源使用量。经常访问的行可以隔离到单个节点上的单行数据片,从而限制对其他行的影响。 | 根据哈希值在所有节点之间分配行,无论流量如何。热门行会影响整个分区的性能。 |
| 扫描排序后的键 | 按字典顺序存储数据,因此非常适合流式传输已排序的数据。 | 根据哈希值分配记录,因此扫描多个连续键需要查询多个节点并汇总结果,这可能会比较慢。支持二级索引(包括高级类型),这可能会减少扫描需求。 |
| 插入多个连续的键 | 按字典顺序存储数据,这意味着单个节点会处理许多连续的键写入操作。这样一来,读取或写入模式最终可能会出现在负责行键空间末尾的平板电脑所在的节点上,从而导致该节点过载。 | 基于哈希值分配键,在写入连续键时在多个节点之间分配负载。 |
| 包含大量列的行 | 虽然 Bigtable 可以支持最大 256 MB 的行,但处理大型行可能会影响性能。Bigtable 针对较小的行进行了优化,因此在设计架构时应考虑单元格组织和数据访问,以避免不必要地将数据分散到多个单元格中。 | 遇到具有大量列或箱的行或记录时,性能欠佳。 |
| 冷启动 | 最适合频繁访问的大型表。如果您在空闲一段时间后开始发送请求(冷启动),则可能会观察到高延迟。这是因为平板电脑的拆分及其在节点之间的分布可能不是最佳的,并且缓存是冷的。在冷启动期间和重新平衡期间,节点之间的分布可能无法完全达到最佳状态,直到几分钟后才能达到最佳状态。 | 性能不会随时间变化,因为数据分布不是基于负载的。虽然缓存需要预热,但索引会保留在内存中,从而最大限度地缩短磁盘搜索时间并降低缓存的重要性。 |
| 许多小表 | 避免创建许多小型表。对于不同的使用情形或架构,使用单独的表是合理的,但不应针对类似的数据使用单独的表,因为这不会改善负载均衡,反而会增加管理开销。 | 大多数记录都位于一个命名空间中,并分组为集合。集合没有特定的架构,但可以为每个集合设置二级索引或扫描操作。将数据拆分为多个集合不会影响性能。 |
| 大型数据集 | 能够存储 EB 级数据集。由于其架构和动态平板拆分,性能不受总数据集大小的影响。 | 从技术上讲,Aerospike 数据库没有大小限制,但 Aerospike 会分别存储索引和记录。这两种类型的数据都可以存储在 不同类型的存储设备上,以提高性能。将索引存储在 RAM 中对于实现低延迟至关重要,但对于非常大的数据集,这可能不可行。例如,如果有 40 亿个对象,复制系数为 2 (RF2),则在全闪存集群中,与主索引关联的内存消耗为 2.5 GiB。在混合内存配置中使用同一示例,其中主索引位于内存中,则会使用 476.8 GiB 的内存。 |
| 扩缩 | 处理和存储是解耦的,可以独立扩缩。单个节点可以处理数百 TB 甚至 PB 的数据块。 | 将索引存储在 RAM 中对于实现低延迟至关重要。在这种情况下,机器必须与存储容量一起纵向扩缩,以考虑主索引。 |
后续步骤
- 了解 Bigtable 架构设计。
- 详细了解 Aerospike。
- 了解 Bigtable 模拟器。
- 探索有关 Google Cloud 的参考架构、图表和最佳做法。查看我们的 Cloud 架构中心。