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

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

检测和更正索引键违规

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

在以下情况下,会发生索引键冲突

  • 属性值和索引键架构数据类型之间存在数据类型不匹配情况。例如,假设 GameScores 表中的一个项目的 TopScore 值为 String。 如果您添加的 全局二级索引 分区键为 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 可以访问哪些 Violation Detector 资源,以及可以使用多少预配置吞吐量。下表描述了这些参数。

参数名称 描述 必需?

awsCredentialsFile

包含您的 AWS 凭证的文件的完全限定名称。凭证文件必须采用以下格式:

accessKey = access_key_id_goes_here secretKey = secret_key_goes_here

dynamoDBRegion

表所在的 AWS 区域。例如: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 将表划分为相应数量的逻辑段和相同数量的扫描线程。

的最大设置为 4096。numOfSegments

对于较大的表,并行扫描通常快于顺序扫描。此外,如果表足够大以跨多个分区,则并行扫描将跨多个分区均匀分配其读取活动。

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

numOfViolations

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

numOfRecords

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

readWriteIOPSPercent

调整在表扫描期间使用的预置读取容量单位的百分比。有效值范围为 1100。 默认值 (25) 表示 Violation Detector 消耗的读取吞吐量不超过表的 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 并写入到您的当前工作目录。

Detection

要检测索引键冲突,请将 Violation Detector 与 --detect 命令行选项结合使用。要显示此选项的工作方式,请考虑ProductCatalog中显示的 为 DynamoDB 中的代码示例创建表和加载数据 表。以下是表中的项目的列表。仅显示主键 (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 格式。文件的第一行是一个标头,然后每个项目一条记录,违反索引键。这些违规记录的字段如下所示:

  • 表哈希键 — 表中项目的分区键值。

  • 表范围键 — 表中项目的排序键值。

  • GSI 哈希键值 — 的分区键值。全局二级索引

  • GSI 哈希密钥违规类型Type ViolationSize Violation

  • GSI 哈希密钥违规说明 — 违规的原因。

  • GSI 哈希键更新值(FOR USER) 在更正模式下,属性的新用户提供的值。—

  • GSI Range Key Value (GSI 范围键值) — 的排序键值。全局二级索引

  • GSI 范围键违规类型 — 或 Type ViolationSize Violation

  • GSI 范围键违规说明 — 违规的原因。

  • GSI Range Key Update Value(FOR USER) 在更正模式下,属性的新用户提供的值。—

  • Delete Blank Attribute When Updated(Y/N) 在更正模式下,仅当以下任一字段为空时,— 才会确定是删除 (Y) 还是保留表中的违规项目—。

    • GSI Hash Key Update Value(FOR USER)

    • GSI Range Key Update Value(FOR USER)

    如果任一字段不为空,则 Delete Blank Attribute When Updating(Y/N) 无效。

注意

输出格式可能会有所不同,具体取决于配置文件和命令行选项。例如,如果表具有简单主键(没有排序键),则输出中不存在排序键字段。

文件中的违规记录可能未按排序顺序。

Correction

要更正索引键冲突,请将 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 具有相同的数量的项目。