检测和纠正索引键违规 - Amazon DynamoDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

检测和纠正索引键违规

在全局二级索引创建的回填阶段,Amazon DynamoDB 会检查表中的每个项目,以确定它是否符合包含在索引中的条件。某些项目可能不符合条件,因为它们会导致索引键冲突。在这些情况下,项目仍保留在表中,但索引没有该项的相应条目。

以下情况下发生索引键冲突

  • 属性值与索引键架构数据类型不匹配。例如,假设 GameScores 表的一个项目的类型 StringTopScore 值。如果您添加的全局二级索引的分区键 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 资源,以及它可以占用的预置吞吐量。下表介绍这些参数。

参数名称 描述 必填?

awsCredentialsFile

包含 Amazon 凭证的文件完全限定名称。凭证文件必须为以下格式:

accessKey = access_key_id_goes_here secretKey = secret_key_goes_here

dynamoDBRegion

表所在的 Amazon 区域。例如:us-west-2

tableName

要扫描的 DynamoDB 表的名称。

gsiHashKeyName

索引分区键的名称。

gsiHashKeyType

索引分区键的数据类型 —StringNumberBinary

S | N | B

gsiRangeKeyName

索引排序键的名称。如果索引只有简单主键(分区键),请不要指定此参数。

gsiRangeKeyType

索引排序键的数据类型 —StringNumberBinary

S | N | B

如果索引只有简单主键(分区键),请不要指定此参数。

recordDetails

是否将索引键违规的完整详细信息写入输出文件。如果设置为 true(默认值),则会报告有关违规项目的完整信息。如果设置为 false,则仅报告违规次数。

recordGsiValueInViolationRecord

是否将违规索引键的值写入输出文件。如果设置为 true(默认值),则会报告键值。如果设置为 false,则不会报告键值。

detectionOutputPath

Violation Detector 输出文件的完整路径。此参数支持写入本地目录或 Amazon Simple Storage Service (Amazon S3)。示例如下:

detectionOutputPath = //local/path/filename.csv

detectionOutputPath = s3://bucket/filename.csv

输出文件中的信息以逗号分隔值 (CSV) 格式显示。如果您没有设置 detectionOutputPath,则输出文件名为 violation_detection.csv,并写入到您当前的工作目录中。

numOfSegments

Violation Detector 扫描表时要使用的并行扫描段数。默认值为 1,表示按顺序扫描表。如果值为 2 或更高,则 Violation Detector 将表划分为多个逻辑段和相同数量的扫描线程。

numOfSegments 最大设置为 4096。

对于较大的表,并行扫描通常比顺序扫描快。此外,如果表大到跨越多个分区,则并行扫描会将其读取活动均匀分布到多个分区。

有关 DynamoDB 中并行扫描的更多信息,请参阅 并行扫描

numOfViolations

写入到输出文件的索引键违规上限。如果设置为 -1(默认值),则扫描整个表。如果设置为正整数,则 Violation Detector 会在遇到该数量的违规后停止。

numOfRecords

要扫描的表中的项目数。如果设置为 -1(默认值),则扫描整个表。如果设置为正整数,Violation Detector 会在扫描表中的该数量项目后停止。

readWriteIOPSPercent

调节表扫描期间使用的预置读取容量单位的百分比。有效值范围为 1100。默认值 (25) 表示违规检测器消耗的表预置读取吞吐量不超过 25%。

correctionInputPath

Violation Detector 更正输入文件的完整路径。如果在更正模式下运行 Violation Detector,则此文件的内容将用于修改或删除表中违反全局二级索引的数据项。

correctionInputPath 文件的格式与 detectionOutputPath 文件相同。这样,您就可以将检测模式的输出作为更正模式下的输入进行处理。

correctionOutputPath

Violation Detector 更正输出文件的完整路径。仅当存在更新错误时创建此文件。

此参数支持写入本地目录或 Amazon S3。示例如下:

correctionOutputPath = //local/path/filename.csv

correctionOutputPath = s3://bucket/filename.csv

输出文件中的信息以 CSV 格式显示。如果您没有设置 correctionOutputPath,则输出文件名为 violation_update_errors.csv,并写入到您当前的工作目录中。

检测

若要检测索引键违规,请将 Violation Detector 与 --detect 命令行选项一起使用。要显示此选项的工作原理,请考虑 为 DynamoDB 中的代码示例创建表和加载数据 中显示的表 ProductCatalog。以下是表中项目的列表。仅显示主键 (Id) 和 Price 属性。

ID(主键) 价格
101 5
102 20
103 200
201 100
202 200
203 300
204 400
205 500

Price 的所有值类型为 Number。但是,由于 DynamoDB 无架构,可以添加具有非数字 Price 项目。例如,假设您将另一项添加到 ProductCatalog 表。

ID(主键) 价格
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 keep Violation 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 ViolationSize 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 ViolationSize 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

现在 ProductCatalogPriceIndex 具有相同数量的项目。