在 DynamoDB 中管理全局二级索引
本节介绍如何在 Amazon DynamoDB 中创建、修改和删除全局二级索引。
创建具有全局二级索引的表
要创建具有一个或多个全局二级索引的表,请使用 CreateTable
和 GlobalSecondaryIndexes
参数。为获得最高的查询灵活性,您可以为每个表创建最多 20 个全局二级索引(默认配额)。
您必须指定一个属性以充当索引分区键。您可以选择为索引排序键指定另一个属性。这些关键属性中的任何一个都不必与表中的关键属性相同。例如,在 GameScores 表(请参阅 在 DynamoDB 中使用全局二级索引),TopScore
和 TopScoreDateTime
都不是关键属性。您可以创建具有分区键 TopScore
以及排序键 TopScoreDateTime
的全局二级索引。您可以使用这样的索引来确定高分与玩游戏时间之间是否存在相关性。
每个索引键属性必须是标量类型 String
、Number
或 Binary
。(它不能是文档或集合。) 您可以将任何数据类型的属性投影到全局二级索引中。其中包括标量、文档和集。有关数据类型的完整列表,请参阅 数据类型。
如果使用预置模式,必须提供索引的 ProvisionedThroughput
设置,包括 ReadCapacityUnits
和 WriteCapacityUnits
。这些预置吞吐量设置与表的设置分开,但行为方式相似。有关更多信息,请参阅 全局二级索引的预调配吞吐量注意事项。
全局二级索引继承基表的读/写入容量模式。有关更多信息,请参阅 在 DynamoDB 中切换容量模式时的注意事项。
注意
回填操作和正在进行的写入操作在全局二级索引中共用写入吞吐量。创建新的 GSI 时,请务必检查您选择的分区键在新索引的分区键值之间生成的数据或流量是否分布不均或缩小。如果发生这种情况,您可能会看到同时发生回填和写入操作并且会限制对基表的写入操作。该服务采取措施最大限度地减少这种情况的可能性,但不会深入了解与索引分区键、所选的预测或索引主键的稀疏程度相关的客户数据的形状。
如果您怀疑新的全局二级索引可能出现分区键值中的数据或流量过窄或偏斜,请先考虑以下方面,然后再向操作重要的表添加新索引。
-
最安全的方法是在应用程序驱动最少流量时添加索引。
-
请考虑在基表和索引上启用 CloudWatch Contributor Insights。这将为您提供有用的流量分布洞察。
-
对于预置容量模式基表和索引,请将新索引的预置写入容量设置为至少是基表的两倍。在过程中观察
WriteThrottleEvents
、ThrottledRequests
、OnlineIndexPercentageProgress
、OnlineIndexConsumedWriteCapacity
和OnlineIndexThrottleEvents
CloudWatch 指标。根据需要调整预置的写入容量,以便在合理的时间内完成回填,而不会对正在进行的操作产生任何重大的限制影响。 -
如果因写入限制而遇到操作影响,请准备取消索引创建,并且提高新 GSI 中的预置写入容量不能解决此问题。
描述表的全局二级索引
要查看表上所有全局二级索引的状态,请使用 DescribeTable
操作。响应的 GlobalSecondaryIndexes
部分显示表上的所有索引,以及各自当前状态 (IndexStatus
)。
全局二级索引的 IndexStatus
为:
-
CREATING
— 索引当前正在创建,但是还不能使用。 -
ACTIVE
— 索引已准备就绪,应用程序可以对索引执行Query
操作。 -
UPDATING
— 索引的预置吞吐量设置正在更改。 -
DELETING
— 索引当前正在删除,不能再使用。
当 DynamoDB 完成构建全局二级索引时,索引状态会从 CREATING
变为 ACTIVE
。
向现有表添加全局二级索引
要将全局二级索引添加到现有表,请使用 UpdateTable
操作和 GlobalSecondaryIndexUpdates
参数。您必须提供以下参数:
-
索引名称。该名称在表的所有索引中必须唯一。
-
索引的键架构。您必须为索引分区键指定一个属性;您可以选择为索引排序键指定另一个属性。这些关键属性中的任何一个都不必与表中的关键属性相同。每个架构属性的数据类型必须是标量:
String
、Number
或Binary
。 -
从表投影到索引中的属性:
-
KEYS_ONLY
— 索引中的每个项目仅包含表的分区键、排序键值以及索引键值。 -
INCLUDE
– 除KEYS_ONLY
中描述的属性外,二级索引还包括您指定的其他非键属性。 -
ALL
— 索引包括源表中的所有属性。
-
-
索引的预置吞吐量,由
ReadCapacityUnits
和WriteCapacityUnits
组成。与表的预吞吐量设置是分开的。
您只能为每个 UpdateTable
操作创建一个全局二级索引。
索引创建的阶段
将新的全局二级索引添加到现有表时,该表在构建索引期间继续可用。但是,新索引不可用于查询操作,直到其状态从 CREATING
变为 ACTIVE
。
注意
创建全局二级索引不会使用 Application Auto Scaling。增加 MIN
Application Auto Scaling 容量不会缩短全局二级索引的创建时间。
DynamoDB 后台分两个阶段构建索引:
- 资源分配
-
DynamoDB 分配构建索引所需的计算和存储资源。
在资源分配阶段,
IndexStatus
属性为CREATING
,Backfilling
属性为 false。使用DescribeTable
操作检索表及其所有二级索引的状态。当索引处于资源分配阶段时,无法删除索引或删除其父表。您也无法修改索引或表的预置吞吐量。您无法在表上添加或删除其他索引。但是,您可以修改这些其他索引的预置吞吐量。
- 回填
-
对于表中的每个项目,DynamoDB 根据其投影确定要写入索引的属性集合(
KEYS_ONLY
、INCLUDE
或ALL
)。然后,它将这些属性写入索引。在回填阶段,DynamoDB 会跟踪表中正在添加、删除或更新的项目。也会根据需要在索引中添加、删除或更新这些项目的属性。在回填阶段,
IndexStatus
属性设置为CREATING
,Backfilling
属性为 true。使用DescribeTable
操作检索表及其所有二级索引的状态。当索引处于回填状态时,您不能删除其父表。但是,您仍然可以删除索引或修改表及其任何全局二级索引的预置吞吐量。
注意
在回填阶段,一些违规项目的写入可能会成功,而另一些则会被拒绝。回填后,对违反新索引的键架构的项目的所有写入操作都将被拒绝。我们建议您在回填阶段完成后运行 Violation Detector 工具,以检测和解决可能发生的任何关键违规。有关更多信息,请参阅 在 DynamoDB 中检测和纠正索引键违规。
当资源分配和回填阶段正在进行中时,索引位于 CREATING
状态。在此期间,DynamoDB 会对表执行读取操作。对于从基表中填充全局二级索引的读取操作,您不需要付费。但是,您需要为写入操作付费,以填充新创建的全局二级索引。
当索引构建完成后,其状态将更改为 ACTIVE
。您不能 Query
或 Scan
索引,直到变为 ACTIVE
。
注意
某些情况下,DynamoDB 会因索引键冲突而无法将表中的数据写入索引。在以下情况下,可能会发生这种情况:
-
属性值的数据类型与索引键架构数据类型不匹配。
-
属性的大小超出索引键属性的最大长度。
-
索引键属性具有空字符串或空二进制属性值。
索引键冲突不会干扰全局二级索引的创建。但是,当索引变为 ACTIVE
后,则索引中不存在违规键。
DynamoDB 提供了一个独立的工具来查找和解决这些问题。有关更多信息,请参阅 在 DynamoDB 中检测和纠正索引键违规。
向大型表添加全局二级索引
构建全局二级索引所需的时间取决于几个因素,例如:
-
表的大小
-
表中有资格包含在索引中的项目数
-
投影到索引中的属性数量
-
索引的预置写入容量
-
在索引构建期间在主表上写入活动
如果要将全局二级索引添加到非常大的表中,则创建过程可能需要很长时间才能完成。要监控进度并确定索引是否具有足够的写入容量,请参阅以下 Amazon CloudWatch 指标:
-
OnlineIndexPercentageProgress
-
OnlineIndexConsumedWriteCapacity
-
OnlineIndexThrottleEvents
有关 DynamoDB 相关 CloudWatch 指标的更多信息,请参阅 DynamoDB 指标。
重要
在创建或更新全局二级索引之前,您可能需要将大量表加入允许列表。请联系 Amazon Support 以将您的表加入允许列表。
如果索引上的预置写入吞吐量设置太低,则索引构建将需要更长的时间才能完成。要缩短构建新的全局二级索引所需的时间,您可以临时增加其预置的写入容量。
注意
作为一般规则,我们建议将索引的预配置写入容量设置为表写入容量的 1.5 倍。对于许多使用案例,这是一个很好的设置。但是,您的实际需求可能更高或更低。
回填索引时,DynamoDB 会使用内部系统容量从表中读取。这是为了最大限度地减少创建索引的影响,并确保您的表不会耗尽读取容量。
但是,传入写入活动的量可能会超过索引的预配置写入容量。这是一种瓶颈,在这种情况下,索引创建需要更多的时间,因为对索引的写入活动受到限制。在索引构建过程中,我们建议您监控索引的 Amazon CloudWatch 指标,以确定其占用的写入容量是否超过预置容量。在瓶颈情况下,您应该增加索引上的预置写入容量,以避免回填阶段的写入限制。
创建索引后,您应该设置其预置的写入容量,以反映应用程序的正常使用情况。
删除全局二级索引
如果您不再需要全局二级索引,可以使用 UpdateTable
操作删除。
您只能为每个 UpdateTable
操作删除一个全局二级索引。
删除全局二级索引时,对父表中的任何读取或写入活动都没有影响。删除过程中,您仍然可以修改其他索引上的预置吞吐量。
注意
-
使用
DeleteTable
操作删除表时,会同时删除该表的全局二级索引。 -
将不会针对全局二级索引的删除操作向您的账户收取费用。
在创建期间修改全局二级索引
在构建索引时,您可以使用 DescribeTable
操作确定它处于哪个阶段。索引的描述包括一个布尔属性 Backfilling
,指示 DynamoDB 当前是否正在使用表中的项目加载索引。如果 Backfilling
为 true,则资源分配阶段已完成,索引现在正在回填。
回填时,您可以更新索引的预置的吞吐量参数。您可能决定这样做是为了加快索引构建速度:您可以在构建索引时增加索引的写入容量,然后再减小它。要查看的预置吞吐量设置,请使用 UpdateTable
操作。索引状态将变为 UPDATING
,Backfilling
为 true,直到索引准备就绪,才可供使用。
在回填阶段,您可以删除正在创建的索引。在此阶段中,您无法在表上添加或删除其他索引。
注意
对于作为 CreateTable
操作的一部分创建的索引,Backfilling
属性未显示在 DescribeTable
输出。有关更多信息,请参阅 索引创建的阶段。