使用哈希-范围主键的性能:Dynamodb



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

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

还有其他人遇到过这种问题并有解决方案吗?

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

然而,您想要知道"最后登录"的需求并不适合NoSQL数据库,因为扫描数据是非常占用CPU和io的。

另一种方法应该是为每个用户创建一个Item(记录),并在该用户上次登录时间的Item上存储一个Attribute(类似于"Column"的概念)。这样,您只需要检索一条特定的记录就可以发现上次登录时间。

如果您还希望保留登录尝试的完整历史记录,可以在单独的表中完成,每个登录尝试使用Hash和Range以及一个Item。这将与上面每个用户只有一个Item的表分开。

您可以尝试将unix时间戳分类,以受益于DynamoDB的查询功能。

示例模式:

  • hash key = date
  • range key = timestamp
  • 其他属性= email

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

使用此模式,特定日期内的所有登录尝试将存储在相同的散列键下。通过提供当前日期作为散列键,可以有效地查询最近的登录。您甚至可以进一步深入,让散列键代表一个小时。

示例查询:

  • KeyConditions: {"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"}

Pro:均匀分布的数据,可扩展的,良好的时间局部性,用于有效的基于时间的查询

Con:查询日期范围/桶的登录尝试次数并不简单。例如,过去3天的登录需要3个单独的查询(每个日期一个)

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

相关内容

  • 没有找到相关文章

最新更新