当前位置: 首页 > 知识库问答 >
问题:

AWS Dynamodb扫描订购?

濮嘉茂
2023-03-14

我们有一个设置,其中各种工作节点执行计算并更新DynamoDB表中的相对状态。该表充当工作节点活动的一种历史记录。看门狗节点需要定期扫描表,并构建一个表示工作节点及其作业的当前状态的对象。因此,我们的应用程序能够扫描表并按时间顺序检索数据(即按时间戳排序)是很重要的。表最终会太大,无法扫描到本地内存进行后期排序,所以我们扫描后无法排序。

从AWS留档读取主键:

DynamoDB使用分区键值作为内部哈希函数的输入。散列函数的输出确定存储项的分区(DynamoDB内部的物理存储)。具有相同分区键的所有项都存储在一起,按排序键值排序。

关于扫描函数的文档似乎没有提到任何关于返回结果顺序的内容。但是上面引用的最后一部分(我用粗体强调的部分)可以解释为扫描的结果是按排序键排序的吗?如果我将所有分区键设置为相同的值,比如“0”,然后使用我的时间戳作为排序键,我可以保证扫描操作将按时间顺序返回数据吗?

请注意:

  • 所有代码都是用Python编写的,因此我使用boto3模块来执行扫描操作。
  • 我们的系统架构师坚决反对更新表中的任何条目以反映其当前状态,或者在作业完成时删除条目。我们只能添加到表中,因此我们需要每次扫描整个内容以确定工作状态。
  • 我在扫描操作中使用强大的读取一致性。

共有2个答案

阎璞瑜
2023-03-14

您最好使用yyyy-mm-dd作为分区键,而不是全部0。每个分区的数据限制为10GB,这也意味着每个分区键值的数据不能超过10GB。

如果您希望能够检索按日期排序的数据,请采用ISO 8601时间戳格式(大致为yyyy-mm-ddThh-mm-ss.sss),将其分割到对您的数据合理的地方,并使用第一部分作为分区键第二部分作为排序键。(这种方法的另一个优点是,您可以对大多数查询使用最终一致的读取,因为假设一天(或一个小时)后数据完全复制是非常安全的。)

如果您可以管理它,那么最好使用Worker ID或Job ID作为分区键,然后使用完整的时间戳作为排序键。

正如@thomasmichaelwallace所提到的,最好使用带有Lambda的DynamoDB流来创建物化视图。

这就是说,如果你正在处理工作在工人上运行,那么你也应该考虑是否可以通过使用工作流服务而不是数据库来实现你的目标。工作流将为您维护作业历史记录和/或当前状态。AWS提供Step功能和简单的工作流程

闻人宜
2023-03-14

从技术上讲,SCAN从不保证顺序(尽管作为观察,缺乏顺序保证似乎意味着分区是随机排序的,但排序仍然是排序的。)

但是,您提出的方法会起作用,但是您将对分区键==0进行查询,而不是进行扫描,然后将返回分区键为0、按排序键排序的所有项目(最多限制和可选的向前/向后排序)。

这就是说,这真的不是迪纳摩希望你使用它的方式。例如,它保证您的分区将热运行(因为您已显式地将所有内容都放在同一分区上),并且此操作将消耗您读取表中每个项目的容量。

我建议研究一些模式,比如使用lambda处理的dynamodb流来构建和维护这个“当前状态”的具体化视图,而不是使用这种昂贵的扫描和糟糕的键设计来“轮询”表。

 类似资料:
  • 在上一章中,Nexpose已成功安装。让我们看看如何运行它以及该工具的功能。Nexpose使用自己的数据库,所以我们要做的第一件事是关闭Kali Linux的数据库。如果两个数据库都在同一个端口上运行,它们就会相互冲突。现在,我们停止postgresql服务。应该记住,在运行Nexpose之前,需要关闭数据库。停止数据库的命令如下: 现在,我们进入到安装Nexpose的位置。除非在安装过程中更改了

  • 在这一章节中,我们将使用在安装工具时设置的用户名和密码登录。在上面的屏幕截图中显示了Metasploit社区的Web界面: 登录后,我们可以访问该帐户并转到用户设置或注销。还可以检查软件更新。 当我们第一次登录时,它会要求我们输入激活密钥。激活密钥将发送到下载工具时输入的电子邮件地址。我们应该确保在下载工具时输入有效的电子邮件地址。 接下来开始创建扫描,我们将点击Project | New Pro

  • 问题内容: 我的Java作业有问题。我遇到了意外的异常,特别是: java.util.NoSuchElementException:找不到行 我正在使用,该程序不断读取任何内容,并重复“无效格式”异常文本。如果输入正确的值,则第一部分通过,然后该部分立即进入此异常。如果输入的值不正确,则它将开始循环异常。 这是我的代码: 问题答案: 您关闭了多个库,这些库关闭了底层库,因此另一个库将不再从同一库和

  • 问题内容: 使用Scanner类中的useDelimiter时遇到一些问题。 如果我有这个输入 美国广播公司 输出将是 AB 然后等到我键入另一个“-”以打印出最后一个字符 但是,如果我没有用户输入数据,而是将字符串插入到Scanner中,则代码将起作用。原因是什么?如何解决?我不想使用StringTokenzier 问题答案: 如果没有等待您输入另一个,则将错误地假定您已完成输入。 我的意思是,

  • 我做了一个程序,要求3个整数来输出三角形的类型。所有内容都成功运行和编译,但是,在要求用户查看是否要再次循环的部分,联机编译器会输出错误: 异常线程"main"java.util.NoSuchElement异常在java.util.Scanner.throwFor(Scanner.java:838)在java.util.Scanner.next(Scanner.java:1347)在Assignm

  • 这一章将会演示如何通过Python的网络连接来开发一个基础的端口扫描器,我们的设计思路是使用socket一遍又一遍的去连接ip与端口的组合的新值,为了方面我们能够快速的完成它,首先需要介绍一点新的概念,for循环: >>> >>> for port in range(1000,1024): ... print "[+] The port is: "+str(port) ... [+] The