【问题标题】:Performance with hash-and-range primary key: Dynamodb哈希和范围主键的性能:Dynamodb
【发布时间】:2015-08-01 10:26:52
【问题描述】:

我正在使用 Node.js 和环回构建一个应用程序。应用程序的一个组件将登录尝试存储到 DynamoDB 中。我对这个数据库很陌生,我遇到了问题。

目前,我的哈希键是一封电子邮件,而我的范围键是发生登录尝试时的 unix 时间戳。本质上,我需要从数据库中获取所有数据,以生成最后一次登录尝试的列表。首先想到的是使用 scan,但是它不允许根据上次登录尝试对列表进行排序。使用 query 的问题在于,我必须访问所有电子邮件,而不仅仅是特定电子邮件的特定项目。我认为我可以使所有哈希值相同,但这会根据 dynamoDB 存储其数据的方式产生性能问题。

有没有其他人遇到过此类问题并有解决方案?

【问题讨论】:

    标签: javascript node.js amazon-dynamodb loopbackjs


    【解决方案1】:

    像 Amazon DynamoDB 这样的 NoSQL 数据库通过特定的主键(“哈希”)来存储和检索数据的效果最好。也可以通过主键加上附加值(“哈希和范围”)来识别数据。

    但是,您想要知道“最后一次登录”的要求并不适合 NoSQL 数据库,因为扫描数据是 CPU 和 IO 密集型的工作。

    另一种方法应该是为每个用户创建一个项目(记录),并在用户上次登录时间的那个项目上存储一个属性(类似于“列”的概念)。这样,您只需检索一条特定记录即可发现上次登录时间。

    如果您还希望保留登录尝试的完整历史记录,这可以在单独的表上完成,其中包含哈希和范围以及每次登录尝试的一个项目。这将与上面每个用户只有一个项目的表分开。

    【讨论】:

    • 感谢所有输入,我应该通过使用二级索引采取不同的路线,只查询失败的登录尝试。
    【解决方案2】:

    您可以尝试对您的 unix 时间戳进行分桶,以从 DynamoDB 的查询功能中受益。

    示例架构:

    • 哈希键 = 日期
    • 范围键 = 时间戳
    • 其他属性 = 电子邮件

    示例项目: {“日期”:“07/31/2015”,“时间戳”:1438393927,“电子邮件”:“abc@def.com”}

    使用此架构,特定日期内的所有登录尝试都将存储在同一个哈希键下。您可以通过提供当前日期作为哈希键来有效地查询最近的登录。您甚至可以进一步向下钻取,让哈希键代表一个小时。

    查询示例:

    • 关键条件:{"date" = "01/01/2015"}
    • ScanIndexForward: false // 最近的登录优先

    示例结果:

    • {“日期”:“01/01/2015”,“时间戳”:1420153200,“电子邮件”:“abc@xyz.com”}
    • {“日期”:“01/01/2015”,“时间戳”:1420153199,“电子邮件”:“def@xyz.com”}
    • {“日期”:“01/01/2015”,“时间戳”:1420153198,“电子邮件”:“abc@xyz.com”}

    专业版:数据分布均匀、可扩展、时间局部性好,可实现高效的基于时间的查询

    骗局:查询日期范围/存储桶内的登录尝试并不那么简单。即,过去 3 天的登录需要 3 个单独的查询(每个日期一个)

    PS:如果您的查询模式需要按日期和电子邮件查询,请使用全局二级索引 (GSI) http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html

    【讨论】:

    • 谢谢!由于这些限制,我最终创建了一个二级索引,并且我只在尝试中显示登录失败,这使得这个过程变得更加容易!
    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 2016-01-21
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多