Amazon DynamoDB
开发人员指南 (API 版本 2012-08-10)
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

检测并更正索引键冲突

在创建全局二级索引创建的回填阶段,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 工具需要使用配置文件。此文件中的参数决定 Violation Detector 可以访问的 DynamoDB 资源以及它可以使用的预配置吞吐量的大小。下表描述了这些参数。

参数名称 说明 必需?

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 将表划分为该数目的逻辑分段以及相等数目的扫描线程。

numOfSegments 的最大设置是 4096。

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

有关 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 并写入当前工作目录。

检测

要检测索引键冲突,请将 Violation Detector 与 --detect 命令行选项配合使用。为演示该选项的工作方式,请考虑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 的主键类型为 NumberString 值与全局二级索引键发生冲突,因此未出现在索引中。

要在这种情况下使用 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 哈希键更新值(针对用户)— 在更正模式下,用户提供的新属性值。

  • GSI 范围键值 — 全局二级索引的排序键值。

  • GSI 范围键冲突类型 — 输入 Type ViolationSize Violation

  • GSI 范围键冲突描述 — 冲突的原因。

  • GSI 范围键更新值(针对用户)— 在更正模式下,用户提供的新属性值。

  • 在更新时删除空白属性 (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 具有相同数目的项目。