面向 DynamoDB 用户的 Bigtable

本文档适用于 DynamoDB 开发者和数据库 希望迁移或设计 使用 Bigtable 作为数据存储区使用的应用。须知事项 本文档,请阅读 Bigtable 概览

Bigtable 和 DynamoDB 是分布式键值对存储, 每秒数百万次查询 (QPS),提供可扩容到 PB 级数据,并且能容忍节点故障。

虽然这些数据库服务的功能集类似, 它们的底层架构和互动细节在 在开始迁移之前需要了解的几个重要事项本文档重点介绍了 两个数据库系统之间的异同。

控制平面

在 DynamoDB 和 Bigtable 中,您可以通过控制平面 以及如何设置和管理资源DynamoDB 是一款无服务器产品,与 DynamoDB 的最高级别互动是表级别。在 即您在预配的容量模式下的 请求单元、选择您的区域和复制,以及管理备份。 Bigtable 不是无服务器产品;您必须创建一个实例 一个或多个集群,其容量取决于节点数 资源。有关这些资源的详细信息,请参阅 实例、集群和节点

下表比较了 DynamoDB 和 Bigtable。

DynamoDB Bigtable
表格 :已定义主要项的一组项 键。表具有备份复制容量设置。 实例:发生复制和连接路由的不同 Google Cloud 可用区或区域中的一组 Bigtable 集群。复制政策是在实例级设置的。

集群:一组位于同一地理位置的 Google Cloud 可用区中的节点,最好与应用服务器共存,以减少延迟时间并实现复制。容量是通过调整每个集群中的节点数量来管理的。

表格: 按行键编入索引。

备份是在表级控制的。
读取容量单位 (RCU) 和写入容量单位 (WCU): 允许每秒读取或写入的单位,具有固定 载荷的大小对于载荷大小较大的每项操作,您都需要支付读取或写入单元费用。

UpdateItem 操作会占用 更新内容的最大尺寸(更新前或更新后) 即使更新涉及商品的部分属性也是如此。
节点:负责 读写数据集群的节点数量会转化为读取、写入和扫描的吞吐量限制。您可以 调整节点数量,具体取决于 延迟时间目标、请求数和载荷大小

SSD 节点的读写吞吐量相同,这与 RCU 和 WCU 之间的明显差异不同。如需更多信息 请参阅典型工作负载下的性能
分区: 由连续行组成的代码块, 与节点共置的固态硬盘 (SSD)。

每个分区都有 1,000 个 WCU、3,000 个 RCU 和 10 GB 数据的硬限制。
平板电脑 :由 选择的存储媒介(SSD 或 HDD)。

表会被分片为片以平衡工作负载。片未存储在 Bigtable 的节点上,而是存储在 Google 的分布式文件系统中,这使得在扩缩时能够快速重新分配数据,并通过维护多个副本来提供额外的持久性。
全局表 :一种提高可用性和 自动传播数据更改,实现数据的耐用性 多个区域。 复制: 一种提高可用性和 自动传播数据更改,实现数据的耐用性 多个区域或同一可用区内的多个可用区之间 区域。
不适用 (N/A) 应用配置文件 :用于指示 Bigtable 如何将客户端 API 调用路由到 适当的集群您还可以使用应用配置文件 来细分归因指标

地理位置复制

复制用于满足客户以下方面的要求:

  • 高可用性,以便在发生可用区或区域故障时确保业务连续性。
  • 将您的服务数据放置在靠近最终用户的位置,以便在他们位于世界各地时提供低延迟服务。
  • 当您需要在一个集群上实现批处理工作负载,并依赖于复制到服务集群时,请使用工作负载隔离。

Bigtable 支持在最多 8 个提供 Bigtable 的 Google Cloud 区域中的多个可用区中部署复制集群。大多数区域都有三个可用区。 Bigtable 会自动跨不同集群复制数据 多主拓扑,这意味着您可以读取和写入任何集群。 Bigtable 复制具有最终一致性。有关详情,请参阅 该 复制功能概览

DynamoDB 提供 全局表 来支持跨多个区域进行表复制。全局表 多主实例,并可跨区域自动进行复制。复制功能 最终一致。

下表列出了复制概念并介绍了其可用性 和 Bigtable。

属性 DynamoDB Bigtable
多主复制 可以。

您可以读取和写入任何全局表。
可以。

您可以读取和写入任何 Bigtable 集群。
一致性模型 具有最终一致性。

全球级的“读己所写”一致性 表格。
最终一致。

为所有用户提供集群级别的读己所写一致性 前提是您将读取和写入操作都发送到了同一个集群。
复制延迟时间 没有服务等级协议 (SLA)。

无服务等级协议 (SLA)。

配置粒度 表级别。 实例级。

一个实例可以包含多个表。
实现 创建一个全局表,并在每个选定项目中包含一个表副本 区域。

区域级别。

通过将表转换为 全局表中。

表必须启用 DynamoDB 流以及流 包含商品的新旧图片。

删除一个区域即可移除该区域中的全局表。
创建包含多个集群的实例。
系统会自动在该实例中的集群之间复制数据。

可用区级。

在 Bigtable 中添加和移除集群 实例。
复制选项 每个表。 每个实例。
流量路由和可用性 流量路由到最近的地理副本。

如果失败,您可以通过应用自定义业务逻辑来确定 将请求重定向到其他区域的时间。
使用应用配置文件进行配置 集群流量路由政策

使用多集群路由将流量自动路由到最近的健康集群。

在发生故障时,Bigtable 支持在集群之间自动故障转移以实现高可用性。
扩缩 写入容量(以 复制的写入请求单元 (R-WRU) 为单位)为 并在副本之间同步

复制读取容量单元 (R-RCU) 为单位的读取容量为 每个副本。
您可以通过在集群内添加或移除节点来独立扩缩集群 根据需要创建每个复制集群
费用 R-WRU 的费用比常规 WRU 多 50%。 您需要为每个集群的节点和存储空间付费。
区域级复制没有网络复制费用 跨可用区
跨区域或跨洲进行复制会产生费用。
服务等级协议 (SLA) 99.999% 99.999%

数据平面

下表比较了 DynamoDB 的数据模型概念 和 Bigtable。表中的每一行都描述了类似的特征。 例如,DynamoDB 中的项类似于 Bigtable 中的行。

DynamoDB Bigtable
:一组属性,可通过其主键在所有其他项中进行唯一标识。上限 允许的大小为 400 KB。 :由行键标识的单个实体。 允许的大小上限为 256 MB。
不适用 列族:由用户指定的命名空间 分组列。
属性 :名称和值的分组。一个 属性值可以是标量、集或文档类型。没有任何 并明确限制属性本身的大小。但是,由于每一项 大小上限为 400 KB,对于只有一个属性的商品, 属性不得超过 400 KB 减去 属性名称。 列限定符:列族中列的唯一标识符。列的完整标识符是 以 column-family:column-qualifier 的形式表示。列限定符包括 按字典顺序排序的列族。

列限定符允许的最大大小为 16 KB。


单元格:单元格用于保存特定行、列 和时间戳。一个单元格包含一个值,值不能超过 100 MB。
主键 : 表格。它可以是分区键,也可以是复合键。

分区键:简单的主键,包含一个 属性。这决定了存储项的物理分区 。允许的最大大小为 2 KB。

排序键:用于确定行顺序的键 一个分区内允许的大小上限为 1 KB。

复合键:由两个属性(分区键和排序键或范围属性)组成的主键。
行键 :表中内容的唯一标识符。 通常由值和分隔符的串联表示。允许的大小上限为 4 KB。

列限定符可用于提供行为 等同于 DynamoDB 排序键的排序依据。

复合键可以使用串联行构建 键和列限定符。

如需了解详情,请参阅“架构转换”示例 设计部分。

存活时间:每个项的时间戳决定了该项何时不再需要。晚于指定的 时间戳,则该项将从您的表中删除,且不使用任何 写入吞吐量。 垃圾回收:每个单元格的时间戳用于确定何时不再需要某个项。垃圾回收删除已过期 处理多个项。垃圾 收集政策在列族级别设置,可以删除 不仅按年龄,还以购买 用户想要维护的版本您不需要满足 在调整集群大小的同时进行压缩。

操作

通过数据平面操作,您可以执行创建、读取、更新和删除 (CRUD) 对表格中的数据执行的操作。下表对类似的数据平面进行了比较 适用于 DynamoDB 和 Bigtable 的操作。

DynamoDB Bigtable
CreateTable CreateTable
PutItem
BatchWriteItem
MutateRow
MutateRows
Bigtable 将写入操作视为更新/插入。
UpdateItem
  • 条件写入
  • 增加和减少

Bigtable 将写入操作视为更新/插入。
GetItem
BatchGetItemQueryScan
`ReadRow`
`ReadRows`(范围、前缀、向后扫描)
Bigtable 支持按行键前缀、正则表达式模式或向前或向后扫描行键范围高效扫描。

数据类型

Bigtable 和 DynamoDB 都是无架构的。我们可以定义列 写入时,不对列的存在或数据强制执行表级 。同样,给定列或属性的数据类型可能与某一行不同 或其他对象不过,DynamoDB API 和 Bigtable API 处理数据类型的方式有所不同。

每个 DynamoDB 写入请求包含每个属性的类型定义, 该值将随读取请求的响应一起返回。

Bigtable 将所有内容均视为字节,并且需要客户端代码 了解类型和编码,以便客户端可以正确解析响应。 例外情况是 增量 运算,将值解释为 64 位大端序有符号整数。

下表比较了 DynamoDB 和 Bigtable。

DynamoDB Bigtable
标量类型 :以数据类型返回 描述符令牌。 字节 :在客户端中,将字节转换为预期类型 应用。

Increment 会将值解释为 64 位大端序有符号整数
:由不重复元素组成的未排序集合。 列族:您可以将列限定符用作集成员名称,并为每个成员提供一个 0 字节作为单元格值。集成员在其列中按字典顺序排序 系列。
映射 :包含 唯一键。 列族
将列限定符用作映射键,并将单元格值用作值的映射键。映射键 按字典顺序排序
列表 :经过排序的项集合。 列限定符
使用插入时间戳实现与 list_append 的等效性 行为,与用于添加前缀的插入时间戳相反。

架构设计

架构设计中的一个重要考虑因素是如何存储数据。在 Bigtable 和 DynamoDB 之间的主要区别在于它们如何处理 以下:

  • 单个值的更新
  • 数据排序
  • 数据版本控制
  • 存储大型值

单个值的更新

DynamoDB 中的 UpdateItem 操作会占用这两者中较大者的写入容量, “之前”和“之后”即使更新涉及 属性。这意味着在 DynamoDB 中,您可能会频繁地 即使它们在逻辑上属于同一行, 其他列。

Bigtable 也可以同样高效地更新单元格,无论单元格是 只能出现在给定行中或数千列中的一个列。有关详情,请参阅 简单写入

数据排序

DynamoDB 会对分区键进行哈希处理并随机分发,而 Bigtable 会按行键的字典顺序存储行,并将所有哈希处理工作交给用户。

随机密钥分配并非适用于所有访问模式的最佳选择。它可以减少 存在热行范围的风险 它会使访问模式涉及扫描 跨分区边界的成本高昂且效率低下。这些无界限扫描 尤其是对于具有时间维度的用例。

处理这种类型的访问模式 - 跨分区扫描 边界 - 需要 DynamoDB 中的二级索引,但 Bigtable 无需二级索引即可处理。 同样,在 DynamoDB 中,查询和扫描操作的扫描数据量上限为 1 MB,超出此上限时需要分页。Bigtable 没有 此类限制。

尽管分区键是随机分布的,但 DynamoDB 仍然具有热 分区 如果所选分区键未均匀分配 会对吞吐量产生不利影响为解决此问题,DynamoDB 建议 写入分片:跨多个逻辑分区随机拆分写入操作 键值。

要应用此设计模式,您需要从固定的 设置值(例如 1 到 10),然后将此数字用作逻辑分区 键。由于您是随机化分区键,因此对表执行的写入操作 均匀分布在所有分区键值中。

Bigtable 将此过程称为 加盐、 而且可以有效地避免热平板电脑

数据版本控制

每个 Bigtable 单元都有一个时间戳和最近的时间戳 始终是任何给定列的默认值。一个常见的使用场景是 时间戳采用版本控制方法 - 将新单元格写入具有 与相应行和列的先前版本数据之间的差异 时间戳。

DynamoDB 没有这种概念, 复杂的架构设计 来支持版本控制此方法涉及为每个项创建两个副本: 一个版本编号前缀为零的副本(例如 v0_), ,以及版本号前缀为 1 的另一个副本,例如 v1_。每次更新内容时,您都会在 更新版本的排序键,并将更新的内容复制到项目中 版本前缀 0。这样可确保使用零前缀找到任何项的最新版本。这种策略不仅需要维护应用端逻辑,还会导致数据写入非常耗费资源且速度缓慢,因为每次写入都需要读取上一个值,然后再执行两次写入。

多行事务与大行容量

Bigtable 不支持多行事务。但是,由于 它可让您存储比内容可以包含很多行的行 DynamoDB,您通常可以通过 设计架构以将相关项分组到共享行键下。对于 有关说明此方法的示例,请参阅单个表设计 图案

存储大型值

由于 DynamoDB 项(类似于 Bigtable 行) 大小上限为 400 KB,存储较大值时,需要拆分值 也可以存储在其他媒体中 S3。两者都有 其中的一些方法会增加应用的复杂性。相比之下, Bigtable 单元最多可存储 100 MB 的数据, 行最大为 256 MB。

架构转换示例

本部分中的示例将架构从 DynamoDB 转换为 Bigtable 具有主要的架构设计差异。

迁移基本架构

商品清单是演示基本键值模式的绝佳示例。 此类架构在 DynamoDB 中可能如下所示。

主键 特性
分区键 排序键 说明 价格 缩略图
帽子 浅顶软呢帽#brandA 采用优质羊毛制成... 30 https://storage…
帽子 浅顶软呢帽#brandB 耐用防水画布适用于... 28 https://storage…
帽子 新闻男孩#brandB 为日常造型增添一丝复古魅力。 25 https://storage…
鞋子 sneakers#brandA 走出时尚与舒适... 40 https://storage…
运动鞋#brandB 经典特色与当代材料相得益彰... 50 https://storage…

在此表中,从 DynamoDB 到 Bigtable 的映射是 简单直接:将 DynamoDB 的复合主键转换为复合 Bigtable 行键。您创建一个列族 (SKU),其中包含 同一组列。

SKU
行键 说明 价格 缩略图
hats#fedoras#brandA 采用优质羊毛制成... 30 https://storage…
hats#fedoras#brandB 耐用防水画布适用于... 28 https://storage…
hats#newsboy#brandB 为日常造型增添一抹复古魅力。 25 https://storage…
鞋子#运动鞋#品牌 A 走出时尚与舒适... 40 https://storage…
鞋子#运动鞋#brandB 经典特色与当代材料相得益彰... 50 https://storage…

单表设计模式

单一表设计模式将多个表分为一组 关系型数据库转换为 DynamoDB 中的单个表。您可以采用前面的示例中的方法,并在 Bigtable 中照搬此架构。不过,最好还是解决架构问题 过程。

在此架构中,分区键包含视频的唯一 ID,这有助于将与该视频相关的所有属性放置在一起,以便更快地访问。鉴于 DynamoDB 的项大小限制,您无法在单行中放置无限数量的自由文本注释。因此,使用模式为 VideoComment#reverse-timestamp 的排序键可将每个评论作为分区中的单独行,并按倒序排列。

假设此视频有 500 条评论,所有者想要移除该视频。 也就是说,所有 条评论和视频属性也需要删除。 要在 DynamoDB 中执行此操作,您需要扫描此分区中的所有键,并 然后发出多个删除请求,遍历每个请求。DynamoDB 支持 多行事务,但是此删除请求太大,无法在单个 交易。

主键 特性
分区键 排序键 UploadDate 格式
0123 视频 2023-09-10T15:21:48 {"480": "https://storage…", "720": "https://storage…", "1080p": "https://storage..."}
VideoComment#98765481 内容
我真的很喜欢。特效令人惊叹。
视频评论#86751345 内容
1:05 处好像有声音。
VideoStatsLikes 计数
3
VideoStatsViews 计数
156
0124 视频 2023-09-10T17:03:21 {"480": "https://storage…", "720": "https://storage…"}
视频评论#97531849 内容
我与所有好友分享了此信息。
视频评论#87616471 内容
这个风格让我想起了一位电影导演,但我说不上原因 。
VideoStats ViewCount
45

请在迁移时修改此架构,以便简化代码 数据请求的速度和成本更低。Bigtable 行包含的内容 比 DynamoDB 项具有更高的容量,并且可处理大量注释。接收者 处理视频收到数百万条评论的情况,那么您可以设置垃圾 收集政策,仅保留固定的 最新评论的数量。

因为计数器可以更新,而不会产生更新整个 也无需拆分您不必使用 UploadDate 列或计算反向时间戳,并确保您的排序键 因为 Bigtable 时间戳会按时间顺序 自动对评论进行排序。这大大简化了架构,并且如果 视频被删除时,您可以事务性地删除该视频所在的行,包括 所有评论。

最后,由于 Bigtable 中的列是按顺序排列的 按字典顺序对列进行重命名,是一种优化方法 支持快速扫描 - 从视频属性到最近的前 N 个 使用单个读取请求 视频。然后,您可以快速浏览其余评论 滚动。

特性
行键 格式 点赞次数 视图 UserComments
0123 {"480": "https://storage…", "720": "https://storage…", "1080p": "https://storage…"} @2023-09-10T15:21:48 3 156 我非常喜欢这个。特效令人惊叹。@ 2023-09-10T19:01:15
1:05 处好像有声音。@ 2023-09-10T16:30:42
0124 {"480": "https://storage…", "720":"https://storage…"} @2023-09-10T17:03:21 45 这种风格让我想起了一位电影导演,但我说不出是谁。@2023-10-12T07:08:51

相邻性列表设计模式

我们来考虑此设计的一个略微不同的版本,DynamoDB 经常将该版本 指的是相邻列表设计模式。

主键 特性
分区键 排序键 DateCreated 详细信息
Invoice-0123 Invoice-0123 2023-09-10T15:21:48 {"discount": 0.10,
"sales_tax_usd":"8",
"due_date":"2023-10-03.."}
Payment-0680 2023-09-10T15:21:40 {"amount_usd": 120, "bill_to":"John…",
"address":"123 Abc St…"}
Payment-0789 2023-09-10T15:21:31 {"amount_usd": 120, "bill_to":"Jane…",
"address":"13 Xyz St..."}
Invoice-0124 Invoice-0124 2023-09-09T10:11:28 {"discount": 0.20,
"sales_tax_usd":"11",
"due_date":"2023-10-03.."}
Payment-0327 2023-09-09T10:11:10 {"amount_usd": 180, "bill_to":"Bob…",
"address":"321 Cba St..."}
Payment-0275 2023-09-09T10:11:03 {"amount_usd": 70, "bill_to":"Kate…",
"address":"21 Zyx St..."}

在此表中,排序键并非基于时间,而是基于付款 ID。 因此您可以使用不同的宽列模式 这些列具有与之前的 示例。

账单 付款
行键 详细信息 0680 0789
0123 {"discount": 0.10,
"sales_tax_usd":"8",
"due_date":"2023-10-03.."}
@ 2023-09-10T15:21:48
{"amount_usd": 120, "bill_to":"John…",
"address":"123 Abc St..."} @ 2023-09-10T15:21:40
{"amount_usd": 120, "bill_to":"Jane…",
"address":"13 Xyz St..."}
@ 2023-09-10T15:21:31
行键 详细信息 0275 0327
0124 {"discount": 0.20,
"sales_tax_usd":"11",
"due_date":"2023-10-03.."}
@ 2023-09-09T10:11:28
{"amount_usd": 70, "bill_to":"Kate…",
"address":"21 Zyx St…"}
@ 2023-09-09T10:11:03
{"amount_usd": 180, "bill_to":"Bob…",
"address":"321 Cba St..."}
@ 2023-09-09T10:11:10

如前面的示例所示,通过正确的架构设计,Bigtable 的宽列模型可以非常强大,并支持许多在其他数据库中需要昂贵的多行事务、次级索引或删除时级联行为的用例。

后续步骤