查询具有少量值的属性的 DynamoDB 最佳实践

DynamoDB best practice for querying attribute with few values

我在 DynamoDB 中有一个 table,它包含如下属性:

OrderId, OrderJson,OrderStatus.

订单状态的值可以是0或1。 我需要能够更新指定订单的状态,并根据状态字段获取订单。 一种选择是使用 scan ,另一种是将状态作为分区键的二级索引,但状态字段的值范围很小。 请建议所描述要求的最佳实践是什么? 谢谢!

我不会选择扫描,因为它不划算或效率不高,除非您的订单很少。

简而言之,您在全球二级索引方面走在了正确的轨道上。 (我假设您在谈论全球二级索引。也有本地二级索引,但我看不出这些对这种情况有多大帮助。

无论如何,我会创建一个 GSI,其中 OrderStatus 作为 Hash 键,OrderId 作为 Range 键。不过,您需要注意几件事。

1) 写入吞吐量。请记住,具有相同 OrderStatus 的订单将写入 GSI 上的同一磁盘。这正是 Dynamo 的工作方式,具有相同哈希键的文档会​​转到相同的位置。这意味着无论您为 table 设置的写入吞吐量是多少,单个磁盘上的写入吞吐量都有一个上限。确保您不会超过该上限。

2) 读取吞吐量。与写入吞吐量几乎相同,但用于读取。读取限制高于写入限制,但仍需注意。

3) 寻呼。每当您使用哈希键(在本例中为 OrderStatus)查询 Dynamo table 时,它都会自动将响应的大小限制为 1 MB。因此,您可能需要发出多个顺序查询请求来读取特定 OrderStatus 的所有订单。

好在所有这些问题都有基本相同的解决方案,"sharding"。在这种情况下,我所说的分片是指为您的 OrderStatus 添加一个后缀。例如,如果 OrderStatus 可以是 1 或 0,您将创建另一个字段,例如OrderShard,可以是 1_0、1_1、1_2、...、1_9、0_0、0_1、0_2 , ..., 0_9。我们基本上只是在 OrderStatus 的末尾添加一个 0 到 9 之间的随机整数,以在 GSI 上创建更多可能的哈希键值。这将意味着您的数据分布在更多磁盘上,解决了 1 和 2,并且您可以进行并行查询请求,解决了大部分的问题 3。

现在您将使用 OrderShard,而不是使用 OrderStatus 作为 GSI 上的哈希键。仍然使用 OrderId 作为 Range 键。此外,如果每个 OrderStatus 值 10 个分片不够,只需增加分片的数量。例如,添加一个 0-99 之间的随机数。您需要多少分片取决于您的规模和吞吐量。