繁体   English   中英

DynamoDB扫描查询和BatchGet

[英]DynamoDB Scan Query and BatchGet

我们有一个Dynamo DB表结构,其中包含哈希和范围作为主键。

Hash = date.random_number
Range = timestamp

如何在X和Y时间戳内获取项目? 由于哈希键附加有random_number,因此必须多次触发查询。 是否可以提供多个哈希值和单个RangeKeyCondition。

在成本和时间方面最有效的是什么?

随机数范围是1到10。

如果我理解正确,那么您的表中的主键定义如下:

Hash Key  : date.random_number 
Range Key : timestamp

您必须记住的一件事是,无论您使用的是GetItem还是Query ,都必须能够计算应用程序中的Hash Key ,才能成功从表中检索一个或多个项目。

将随机数用作Hash Key一部分很有意义,因此您的记录可以均匀地分布在DynamoDB分区上,但是,您必须以一种方式使应用程序仍然可以在需要检索这些数字时计算这些数字。记录。

考虑到这一点,让我们创建指定需求所需的查询。 可用于从表中获取多个项目的本机AWS DynamoDB操作是:

Query, BatchGetItem and Scan
  • 为了使用BatchGetItem您需要事先知道整个主键(哈希键和范围键),事实并非如此。

  • Scan操作实际上会遍历表的每条记录,我认为这对于您的要求是不必要的。

  • 最后,使用Query操作,您可以从表中检索一个或多个项目,这些表将EQ (等式)运算符应用于Hash Key以及当您没有整个Range Key或需要时可以使用的许多其他运算符匹配多个。

Range Key条件的操作员选项为: EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN

在我看来,最适合您要求的是BETWEEN运算符,也就是说,让我们看看如何使用所选的SDK构建查询:

Table table = dynamoDB.getTable(tableName);

String hashKey = "<YOUR_COMPUTED_HASH_KEY>";
String timestampX = "<YOUR_TIMESTAMP_X_VALUE>";
String timestampY = "<YOUR_TIMESTAMP_Y_VALUE>";

RangeKeyCondition rangeKeyCondition = new RangeKeyCondition("RangeKeyAttributeName").between(timestampX, timestampY);

        ItemCollection<QueryOutcome> items = table.query("HashKeyAttributeName", hashKey,
            rangeKeyCondition,
            null, //FilterExpression - not used in this example
            null,  //ProjectionExpression - not used in this example
            null, //ExpressionAttributeNames - not used in this example
            null); //ExpressionAttributeValues - not used in this example

您可能希望查看以下文章,以获取有关DynamoDB主键的更多信息: DynamoDB:何时使用哪种PK类型?

问题:由于附加了random_number,我担心的是多次查询。 有没有一种方法可以将这些查询组合在一起,并一次命中dynamoDB?

您的担心是完全可以理解的,但是,通过BatchGetItem获取所有记录的唯一方法是知道要获取的所有记录的整个主键(HASH + RANGE)。 虽然最大程度地减少到服务器的HTTP往返传输乍看起来似乎是最好的解决方案,但该文档实际上建议您按照自己的方式进行操作,以避免热分区和配置吞吐量的不均匀使用:

设计跨表中项目的统一数据访问

“由于您是对哈希键进行随机化,因此每天对表的写入会平均分布在所有哈希键值上;这将产生更好的并行性和更高的整体吞吐量。在给定的一天,您仍然需要查询每个2014-07-09.N键(其中N是1到200),并且您的应用程序需要合并所有结果。但是,您将避免只使用一个键“热”哈希键承担所有工作量。”

来源: http//docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html

这里还有一个有趣的观点,建议在单个分区中适当地使用读取...如果您从哈希键中删除随机数,以便一次就能获得所有记录,那么无论如何,您都可能会遇到这个问题如果您使用ScanQueryBatchGetItem

查询和扫描准则-避免突发的读取活动

“请注意,这不仅是扫描使用的容量单位爆发问题,而且还因为扫描可能会消耗同一分区中的所有容量单位,因为扫描请求会读取每个容量单位旁边的项目这意味着该请求正在命中同一分区,导致其所有容量单位被消耗,并限制了对该分区的其他请求。如果读取数据的请求已分散在多个分区中,则该操作不会限制特定的分区。”

最后,由于您正在使用时间序列数据,因此研究文档建议的一些最佳实践也可能会有所帮助:

了解时间序列数据的访问模式

对于您创建的每个表,您指定吞吐量要求。 DynamoDB分配和保留资源,以持续的低延迟处理您的吞吐量需求。 在设计应用程序和表时,应考虑应用程序的访问模式,以最有效地利用表资源。

假设您设计一个表来跟踪客户在您网站上的行为,例如他们单击的URL。 您可以将表设计为具有哈希和范围类型主键,其中客户ID为哈希属性,日期/时间为范围属性。 在此应用程序中,客户数据会随着时间无限增长。 但是,应用程序对表中所有项目的访问方式可能显示不均匀,其中最新客户数据更相关,并且您的应用程序可能更频繁地访问最新项目,并且随着时间的流逝这些项目被访问的次数减少,最终,较旧的项目很少访问。 如果这是已知的访问模式,则可以在设计表架构时将其考虑在内。 您可以使用多个表来存储这些项目,而不是将所有项目存储在一个表中。 例如,您可以创建表来存储每月或每周数据。 对于存储最近一个月或一周中数据访问率较高,要求更高吞吐量的表,对于存储较旧数据的表,您可以降低吞吐量并节省资源。

您可以通过在吞吐量设置较高的一个表中存储“热”项,在吞吐量设置较低的另一表中存储“冷”项来节省资源。 您只需删除表即可删除旧项目。 您可以选择将这些表备份到其他存储选项,例如Amazon Simple Storage Service(Amazon S3)。 删除整个表比逐个删除项要有效得多,因为删除操作与放置操作一样多,这实际上使写入吞吐量增加了一倍。

来源: http//docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM