管理全局二级索引 - Amazon DynamoDB
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

管理全局二级索引

本节介绍如何在 Amazon DynamoDB 中创建、修改和删除全局二级索引。

创建具有全局二级索引的表

要创建具有一个或多个全局二级索引的表,请使用带 CreateTable 参数的 GlobalSecondaryIndexes 操作。为获得最高的查询灵活性,您可以为每个表创建最多 20 个全局二级索引(默认配额)。

您必须指定一个属性以用作索引分区键。您可以选择为索引排序键指定另一个属性。这些键属性中的任意一个属性不必与表中的键属性相同。例如,在 GameScores 表中(请参阅在 DynamoDB 中使用全局二级索引),TopScoreTopScoreDateTime 都不是键属性。您可以创建具有分区键 全局二级索引 和排序键 TopScoreTopScoreDateTime。 您可以使用此类索引来确定高分数与游戏玩游戏的时间之间是否存在关联。

每个索引键属性必须是 StringNumberBinary 类型的标量。 (它不能是文档或集。) 您可以将任何数据类型的属性投影到全局二级索引中。这包括标量、文档和集。有关数据类型的完整列表,请参阅数据类型

如果使用预置模式,则必须为索引提供 ProvisionedThroughput 设置,包括 ReadCapacityUnitsWriteCapacityUnits。 这些预置吞吐量设置独立于表的设置,但行为方式类似。有关更多信息,请参阅全局二级索引的预配置吞吐量注意事项

全局二级索引继承基表的读/写入容量模式。有关更多信息,请参阅更改读/写容量模式时的注意事项

描述表的全局二级索引

要查看表上所有全局二级索引的状态,请使用 DescribeTable 操作。响应的 GlobalSecondaryIndexes 部分显示表上的所有索引以及每个索引的当前状态 (IndexStatus)。

IndexStatus 将是以下之一:全局二级索引

  • CREATING — 当前正在创建索引,但尚不可供使用。

  • ACTIVE — 该索引已准备就绪,应用程序可以对索引执行 Query 操作。

  • UPDATING — 正在更改索引的预置吞吐量设置。

  • DELETING — 当前正在删除索引,并且不再可用。

在 DynamoDB 构建完 全局二级索引 后,索引状态将从 CREATING 更改为 ACTIVE

将 全局二级索引 添加到现有表

要将 全局二级索引 添加到现有表,请将 UpdateTable 操作与 GlobalSecondaryIndexUpdates 参数结合使用。您必须提供以下内容:

  • 索引名称。该名称在表上的所有索引中必须是唯一的。

  • 索引的键架构。您必须为索引分区键指定一个属性;您可以选择为索引排序键指定另一个属性。这些键属性中的任意一个属性不必与表中的键属性相同。每个架构属性的数据类型必须为标量:StringNumberBinary

  • 要从表投影到索引的属性:

    • KEYS_ONLY— 索引中的每个项目仅包含表分区键和排序键值以及索引键值。

    • INCLUDE— 除了KEYS_ONLY中描述的属性之外,二级索引还包含您指定的其他非键属性。

    • ALL— 索引包括源表中的所有属性。

  • 索引的预置吞吐量设置,包括 ReadCapacityUnitsWriteCapacityUnits。 这些预置吞吐量设置独立于表的设置。

您只能为每个 全局二级索引 操作创建一个 UpdateTable

索引创建的阶段

当您将新的 全局二级索引 添加到现有表时,该表在构建索引时继续可用。但是,新索引对查询操作不可用,直到其状态从 CREATING 变为 ACTIVE

在后台,DynamoDB 分两个阶段构建索引:

资源分配

DynamoDB 分配构建索引所需的计算和存储资源。

在资源分配阶段,IndexStatus 属性为 CREATINGBackfilling 属性为 false。使用 DescribeTable 操作可检索表及其所有二级索引的状态。

当索引处于资源分配阶段时,您无法删除索引或删除其父表。您也无法修改索引或表的预置吞吐量。您无法在表上添加或删除其他索引。但是,您可以修改这些其他索引的预置吞吐量。

回填

对于表中的每个项目,DynamoDB 会根据其投影(KEYS_ONLYINCLUDEALL)确定要写入索引的一组属性。然后,它会将这些属性写入到索引中。在回填阶段,DynamoDB 会跟踪表中正在添加、删除或更新的项目。这些项目中的属性也会根据情况在索引中添加、删除或更新。

在回填阶段,IndexStatus 属性设置为 CREATINGBackfilling 属性为 true。使用 DescribeTable 操作可检索表及其所有二级索引的状态。

当索引正在回填时,您无法删除其父表。但是,您仍然可以删除索引或修改表及其任何全局二级索引的预置吞吐量。

注意

在回填阶段,违规项的某些写入可能会成功,而其他写入可能会被拒绝。在回填后,将拒绝对违反新索引键架构的项目进行的所有写入。我们建议您在回填阶段完成后运行 Violation Detector 工具,以检测并解决可能已发生的任何关键违规。有关更多信息,请参阅检测和更正索引键违规

当资源分配和回填阶段正在进行时,索引将处于 CREATING 状态。在此期间,DynamoDB 对表执行读取操作。此读取活动不收取费用。

在索引构建完成后,其状态更改为 ACTIVE。 在索引处于 Query 状态之前,您无法对索引执行 ScanACTIVE 操作。

注意

某些情况下,DynamoDB 会因索引键冲突而无法将表中的数据写入索引。在以下情况下,可能会发生这种情况:

  • 属性值的数据类型与索引键架构数据类型不匹配。

  • 属性的大小超出索引键属性的最大长度。

  • 索引键属性具有空字符串或空二进制属性值。

索引键冲突不会干扰 全局二级索引 创建。但是,当索引变为 ACTIVE 时,索引中不存在“违规”键。

DynamoDB 提供查找和解决这些问题的独立工具。有关更多信息,请参阅检测和更正索引键违规

将 全局二级索引 添加到大型表

构建 全局二级索引 所需的时间取决于一些因素,例如:

  • 表的大小

  • 表中有资格包含在索引中的项目的数量

  • 投影到索引中的属性的数量

  • 索引的预置写入容量

  • 在索引构建期间在主表上写入活动

如果要将全局二级索引添加到非常大的表,则创建过程可能需要很长时间才能完成。要监控进度并确定索引是否具有足够的写入容量,请参阅以下 Amazon CloudWatch 指标:

  • OnlineIndexPercentageProgress

  • OnlineIndexConsumedWriteCapacity

  • OnlineIndexThrottleEvents

注意

有关与 CloudWatch 相关的 DynamoDB 指标的更多信息,请参阅DynamoDB 指标

如果索引上的预置写入吞吐量设置过低,则索引构建需要更长时间才能完成。要缩短构建新 全局二级索引 所需的时间,您可以临时增加其预置写入容量。

注意

一般来说,我们建议将索引的预置写入容量设置为表写入容量的 1.5 倍。对于许多使用案例来说,这是很好的设置。但是,您的实际要求可能更高或更低。

在回填索引时,DynamoDB 使用内部系统容量从表中读取。这是为了最大程度地减小索引创建的影响,并确保您的表不会耗尽读取容量。

但是,传入的写入活动量可能会超过索引的预置写入容量。这是一种瓶颈情形,其中,索引创建需要更多时间,因为对索引的写入活动受到限制。在索引构建期间,我们建议您监控索引的 Amazon CloudWatch 指标,以确定其占用的写入容量是否超过其预置容量。在瓶颈场景中,您应增加索引上的预置写入容量,以避免在回填阶段出现写入限制。

创建索引后,您应设置其预置写入容量以反映您的应用程序的正常使用量。

删除集群全局二级索引

如果您不再需要某个全局二级索引,则可使用 UpdateTable 操作将其删除。

每个 全局二级索引 操作只能删除一个 UpdateTable

在删除 全局二级索引 时,对父表中的任何读取或写入活动没有影响。在删除过程中,您仍然可以修改其他索引上的预置吞吐量。

注意

当您使用 DeleteTable 操作删除表时,表上的所有全局二级索引也将被删除。

在创建过程中修改全局二级索引

在构建索引时,您可以使用 DescribeTable 操作确定索引所处的阶段。索引的描述包括布尔属性 Backfilling,以指示 DynamoDB 当前是否正在加载带表中项目的索引。如果 Backfilling 为 true,则资源分配阶段已完成,并且索引正在回填。

在回填过程中,您可以更新索引的预置吞吐量参数。您可能决定这样做来加速索引构建:您可以在构建索引时增加索引的写入容量,然后减少它。要修改索引的预置吞吐量设置,请使用 UpdateTable 操作。索引状态将更改为 UPDATING,并且 Backfilling 为 true,直到索引可供使用。

在回填阶段,您可以删除正在创建的索引。在此期间,您无法在表上添加或删除其他索引。

注意

对于作为 CreateTable 操作的一部分创建的索引,Backfilling 属性不会显示在 DescribeTable 输出中。有关更多信息,请参阅索引创建的阶段