DynamoDB - 从分区键列表中获取对象的大多数 efficient/cheap 方式?
DynamoDB - Most efficient/cheap way of getting a objects from a list of partition keys?
假设我的客户端有一个 PK 列表:
PKs = [uuid1, uuid2, uuid3, uuid4, ...]
我需要获取具有这些相应 PK 的对象。
我可以想到 3 种方法:
交易
使用 TransactGetItems,我可以一次获取 10 个项目,所以我会单独获取每个项目,直到我全部获取它们
批量获取物品
与事务相同,但不是事务性的,我一次可以获取 25 个项目。
带过滤器的查询(可能很乱)
我可以改为使用具有不可变属性的 GSI 作为分区键,并将原始分区键设置为属性,然后我可以在条件表达式中链接一堆 "ORs"。
例如 (boto3):
table.query(
KeyConditionExpression=Key('gsi1_pk').eq('metadata'),
#Bunch of ORs togheter
FilterExpression=Attr('pk').eq('uuid1') | Attr('pk').eq('uuid2') ...
Index='GSI1-Index1'
)
现在,根据定价页面:
DynamoDB charges one read request unit for each strongly consistent
read (up to 4 KB), two read request units for each transactional read,
and one-half read request unit for each eventually consistent read
我不确定 1 read 是什么,它考虑了返回的每个对象还是扫描的每个对象?每个不同的请求至少是 1 个 RCU 还是它们加起来直到达到 1 个 RCU?
以上 3 个示例中的哪一个是遵循 DynamoDB 定价系统的最便宜的?还有其他方法吗?
计算加分。
嗯,交易应该是你最后的选择,因为这与交易逻辑无关。
BatchGetItems
每个项目消耗 1RCU,但是,Query
根据项目的总大小消耗 RCU queried(不是 return编!!)。如果您要查询 table 和 return 100 个项目,但每个项目的大小为 1kb(没有过滤器),它将是 400kb,因此消耗了 10 个 RCU(计算可能有误,写入速度非常快,但是您得到这个想法)。所以在很多情况下查询要便宜得多,除了你的。在您的情况下,您只需扫描整个 table,因为据我所知,HASH 是静态的。
你最好的选择是BatchGetItems
,但是有一个很大的然而这里...
你怎么最终只有你想要的 ID?这不是 NoSQL 模式。您可能做的是规范化不适用于 DynamoDB 的数据。您应该对其进行去规范化,以便在可以获得这些 ID 列表的地方也可以获得它们的相关属性。如果您查询某些内容并获取 ID,那么对 ID 的另一个请求只是说它的 NORMALIZED 和 DynamoDB 不适合它。
我会建议你 re-consider 你的数据设计和访问模式。
假设我的客户端有一个 PK 列表:
PKs = [uuid1, uuid2, uuid3, uuid4, ...]
我需要获取具有这些相应 PK 的对象。
我可以想到 3 种方法:
交易
使用 TransactGetItems,我可以一次获取 10 个项目,所以我会单独获取每个项目,直到我全部获取它们
批量获取物品
与事务相同,但不是事务性的,我一次可以获取 25 个项目。
带过滤器的查询(可能很乱)
我可以改为使用具有不可变属性的 GSI 作为分区键,并将原始分区键设置为属性,然后我可以在条件表达式中链接一堆 "ORs"。
例如 (boto3):
table.query(
KeyConditionExpression=Key('gsi1_pk').eq('metadata'),
#Bunch of ORs togheter
FilterExpression=Attr('pk').eq('uuid1') | Attr('pk').eq('uuid2') ...
Index='GSI1-Index1'
)
现在,根据定价页面:
DynamoDB charges one read request unit for each strongly consistent read (up to 4 KB), two read request units for each transactional read, and one-half read request unit for each eventually consistent read
我不确定 1 read 是什么,它考虑了返回的每个对象还是扫描的每个对象?每个不同的请求至少是 1 个 RCU 还是它们加起来直到达到 1 个 RCU?
以上 3 个示例中的哪一个是遵循 DynamoDB 定价系统的最便宜的?还有其他方法吗?
计算加分。
嗯,交易应该是你最后的选择,因为这与交易逻辑无关。
BatchGetItems
每个项目消耗 1RCU,但是,Query
根据项目的总大小消耗 RCU queried(不是 return编!!)。如果您要查询 table 和 return 100 个项目,但每个项目的大小为 1kb(没有过滤器),它将是 400kb,因此消耗了 10 个 RCU(计算可能有误,写入速度非常快,但是您得到这个想法)。所以在很多情况下查询要便宜得多,除了你的。在您的情况下,您只需扫描整个 table,因为据我所知,HASH 是静态的。
你最好的选择是BatchGetItems
,但是有一个很大的然而这里...
你怎么最终只有你想要的 ID?这不是 NoSQL 模式。您可能做的是规范化不适用于 DynamoDB 的数据。您应该对其进行去规范化,以便在可以获得这些 ID 列表的地方也可以获得它们的相关属性。如果您查询某些内容并获取 ID,那么对 ID 的另一个请求只是说它的 NORMALIZED 和 DynamoDB 不适合它。
我会建议你 re-consider 你的数据设计和访问模式。