在 DynamoDB 中检测和纠正索引键违规
在全局二级索引创建的回填阶段,Amazon DynamoDB 会检查表中的每个项目,以确定它是否符合包含在索引中的条件。某些项目可能不符合条件,因为它们会导致索引键冲突。在这些情况下,项目仍保留在表中,但索引没有该项的相应条目。
以下情况下发生索引键冲突:
-
属性值与索引键架构数据类型不匹配。例如,假设
GameScores
表的一个项目的类型String
为TopScore
值。如果您添加的全局二级索引的分区键TopScore
类型Number
,则表中的项目将违反索引键。 -
表的属性值超出索引键属性的最大长度。分区键的最大长度为 2048 字节,排序键的最大长度为 1024 字节。如果表中的任何相应属性值超过这些限制,则表中的项目将违反索引键。
注意
如果为用作索引键的属性设置了字符串或二进制属性值,则属性值的长度必须大于零;否则,表中的项将与索引键冲突。
此工具目前不会标记此索引键冲突。
如果发生索引键冲突,回填阶段将继续不会中断。但是,索引中不包含任何违规项目。回填阶段完成后,所有违反新索引键架构的项目写入操作都将被拒绝。
要标识和修复表中违反索引键的属性值,请使用 Violation Detector 工具。要运行 Violation Detector,您需要创建一个配置文件,该文件指定要扫描的表的名称、全局二级索引分区键和排序键的名称和数据类型,以及在发现任何索引键冲突时要执行的操作。Violation Detector 可以在以下两种不同模式之一运行:
-
检测模式— 检测索引键违规。使用检测模式报告表中会导致全局二级索引中键违规的项目。(您可以选择要求在找到这些违规表项时立即删除它们。) 检测模式的输出将写入文件,您可以使用该文件进行进一步分析。
-
更正模式— 更正索引键冲突。在更正模式下,Violation Detector 从检测模式中读取与输出文件格式相同的输入文件。更正模式从输入文件中读取记录,并且对于每条记录,它会删除或更新表中的相应项目。(请注意,如果选择更新项目,则必须编辑输入文件并为这些更新设置适当的值。)
下载并运行 Violation Detector
Violation Detector 可作为可执行 Java 归档文件(.jar
文件)提供,并在 Windows、macOS 或 Linux 计算机上运行。Violation Detector 需要 Java 1.7(或更高版本)和 Apache Maven。
按照 README.md
文件说明下载并使用 Maven 安装 Violation Detector。
要启动 Violation Detector,请转至生成 ViolationDetector.java
的目录并输入以下命令。
java -jar ViolationDetector.jar [options]
Violation Detector 命令行接受以下选项:
-
-h | --help
— 输出 Violation Detector 的使用摘要和选项。 -
-p | --configFilePath
value
— Violation Detector 配置文件的完全限定名称。有关更多信息,请参阅 Violation Detector 配置文件。 -
-t | --detect
value
— 检测表中的索引键违规,并将其写入 Violation Detector 输出文件。如果此参数的值设置为keep
,则不会修改带有键违规的项目。如果值设置为delete
,则会从表中删除带有键违规的项目。 -
-c | --correct
value
— 从输入文件中读取索引键冲突,并对表中的项目采取纠正措施。如果此参数的值设置为update
,则具有键违规的项目将使用新的不违规值进行更新。如果值设置为delete
,则会从表中删除带有键违规的项目。
Violation Detector 配置文件
在运行时,Violation Detector 工具需要配置文件。此文件中的参数确定违规检测器可以访问哪些 DynamoDB 资源,以及它可以占用的预置吞吐量。下表介绍这些参数。
参数名称 | 描述 | 必填? |
---|---|---|
|
包含 Amazon 凭证的文件完全限定名称。凭证文件必须为以下格式:
|
是 |
|
表所在的 Amazon 区域。例如: |
是 |
|
要扫描的 DynamoDB 表的名称。 |
是 |
|
索引分区键的名称。 |
是 |
|
索引分区键的数据类型 —
|
是 |
|
索引排序键的名称。如果索引只有简单主键(分区键),请不要指定此参数。 |
否 |
|
索引排序键的数据类型 —
如果索引只有简单主键(分区键),请不要指定此参数。 |
否 |
|
是否将索引键违规的完整详细信息写入输出文件。如果设置为 |
否 |
|
是否将违规索引键的值写入输出文件。如果设置为 |
否 |
|
Violation Detector 输出文件的完整路径。此参数支持写入本地目录或 Amazon Simple Storage Service (Amazon S3)。示例如下:
输出文件中的信息以逗号分隔值 (CSV) 格式显示。如果您没有设置 |
否 |
|
Violation Detector 扫描表时要使用的并行扫描段数。默认值为 1,表示按顺序扫描表。如果值为 2 或更高,则 Violation Detector 将表划分为多个逻辑段和相同数量的扫描线程。
对于较大的表,并行扫描通常比顺序扫描快。此外,如果表大到跨越多个分区,则并行扫描会将其读取活动均匀分布到多个分区。 有关 DynamoDB 中并行扫描的更多信息,请参阅 并行扫描。 |
否 |
|
写入到输出文件的索引键违规上限。如果设置为 |
否 |
|
要扫描的表中的项目数。如果设置为 -1(默认值),则扫描整个表。如果设置为正整数,Violation Detector 会在扫描表中的该数量项目后停止。 |
否 |
|
调节表扫描期间使用的预置读取容量单位的百分比。有效值范围为 |
否 |
|
Violation Detector 更正输入文件的完整路径。如果在更正模式下运行 Violation Detector,则此文件的内容将用于修改或删除表中违反全局二级索引的数据项。
|
否 |
|
Violation Detector 更正输出文件的完整路径。仅当存在更新错误时创建此文件。 此参数支持写入本地目录或 Amazon S3。示例如下:
输出文件中的信息以 CSV 格式显示。如果您没有设置 |
否 |
检测
若要检测索引键违规,请将 Violation Detector 与 --detect
命令行选项一起使用。要显示此选项的工作原理,请考虑 ProductCatalog
表。以下是表中项目的列表。仅显示主键 (Id
) 和 Price
属性。
ID(主键) | Price |
---|---|
101 |
5 |
102 |
20
|
103 |
200
|
201 |
100
|
202 |
200
|
203 |
300
|
204 |
400
|
205 |
500
|
Price
的所有值类型为 Number
。但是,由于 DynamoDB 无架构,可以添加具有非数字 Price
项目。例如,假设您将另一项添加到 ProductCatalog
表。
ID(主键) | Price |
---|---|
999 |
"Hello" |
该表现在共有 9 个项目。
现在,您将新的全局二级索引添加到表中:PriceIndex
。此索引的主键为分区键 Price
,类型为 Number
。构建索引后,它将包含 8 个项目-但 ProductCatalog
表中有 9 个项目。这种差异的原因是,"Hello"
值是类型 String
,但 PriceIndex
具有 Number
类型的主键。String
值违反了全局二级索引键,因此不出现在索引中。
若要在这种情况下使用 Violation Detector,请首先创建一个配置文件,如下所示。
# Properties file for violation detection tool configuration. # Parameters that are not specified will use default values. awsCredentialsFile = /home/alice/credentials.txt dynamoDBRegion = us-west-2 tableName = ProductCatalog gsiHashKeyName = Price gsiHashKeyType = N recordDetails = true recordGsiValueInViolationRecord = true detectionOutputPath = ./gsi_violation_check.csv correctionInputPath = ./gsi_violation_check.csv numOfSegments = 1 readWriteIOPSPercent = 40
接下来,您运行 Violation Detector,如以下示例所示。
$
java -jar ViolationDetector.jar --configFilePath config.txt --detect keepViolation detection started: sequential scan, Table name: ProductCatalog, GSI name: PriceIndex Progress: Items scanned in total: 9, Items scanned by this thread: 9, Violations found by this thread: 1, Violations deleted by this thread: 0 Violation detection finished: Records scanned: 9, Violations found: 1, Violations deleted: 0, see results at: ./gsi_violation_check.csv
如果 recordDetails
配置参数设置为 true
,Violation Detector 将每个违规的详细信息写入输出文件,如以下示例所示。
Table Hash Key,GSI Hash Key Value,GSI Hash Key Violation Type,GSI Hash Key Violation Description,GSI Hash Key Update Value(FOR USER),Delete Blank Attributes When Updating?(Y/N) 999,"{""S"":""Hello""}",Type Violation,Expected: N Found: S,,
输出文件采用 CSV 格式。文件中的第一行是标题,后面是违反索引键的每个项目的一条记录。这些违规记录的字段如下:
-
Table hash key(表哈希键)– 表中项目的分区键值。
-
Table range key(表范围键)– 表中项目的排序键值。
-
GSI hash key value(GSI 哈希键值)– 全局二级索引的分区键值。
-
GSI hash key violation type(GSI 哈希键违规类型)–
Type Violation
或Size Violation
。 -
GGSI hash key violation description(GSI 哈希键违规描述)– 违规的原因。
-
GSI hash key update Value(FOR USER) [GSI 哈希键更新值(针对用户)] – 在更正模式下,用户为属性提供的新值。
-
GSI range key value(GSI 范围键值)– 全局二级索引的排序键值。
-
GSI range key violation type(GSI 范围键违规类型)–
Type Violation
或Size Violation
。 -
GSI range key violation description(GSI 范围键违规描述)– 违规的原因。
-
GSI range key update Value(FOR USER) [GSI 范围键更新值(针对用户)] – 在更正模式下,用户为属性提供的新值。
-
Delete blank attribute when Updating(Y/N) [在更新时删除空白属性(是/否)] – 在更正模式下,确定是删除 (Y) 还是保留 (N) 表中违规项目,但仅当以下任一字段为空时:
-
GSI Hash Key Update Value(FOR USER)
-
GSI Range Key Update Value(FOR USER)
如果这些字段中的任何一个不为空,则
Delete Blank Attribute When Updating(Y/N)
无效。 -
注意
输出格式可能有所不同,具体取决于配置文件和命令行选项。例如,如果表具有简单主键(没有排序键),则输出中不会出现排序键字段。
文件中的违规记录可能不按排序顺序排列。
纠正
要更正索引键冲突,请将 Violation Detector 与 --correct
命令行选项一起使用。在更正模式下,Violation Detector 读取 correctionInputPath
参数指定的输入文件。此文件具有的格式与 detectionOutputPath
文件相同,以便您可以使用检测输出作为更正的输入。
Violation Detector 提供了两种不同的方法来纠正索引键违规:
-
删除违反— 删除具有违反属性值的表项。
-
更新违反— 更新表项目,将违规属性替换为不违规的值。
无论哪种情况,都可以使用检测模式的输出文件作为更正模式的输入。
继续 ProductCatalog
示例,假设您要从表中删除违规项目。为此,请使用以下命令行。
$
java -jar ViolationDetector.jar --configFilePath config.txt --correct delete
此时,系统将要求您确认是否要删除违规项目。
Are you sure to delete all violations on the table?y/n
y
Confirmed, will delete violations on the table... Violation correction from file started: Reading records from file: ./gsi_violation_check.csv, will delete these records from table. Violation correction from file finished: Violations delete: 1, Violations Update: 0
现在 ProductCatalog
和 PriceIndex
具有相同数量的项目。