0

我正在研究在 Amazon DynamoDB 之上实现可扩展的无序对象集合。到目前为止,已经考虑了以下选项:

  1. 使用 DynamoDB 文档数据类型(地图、列表)并使用文档路径来访问独立项目。这对于收集限制为 400KB 的数据有一个明显的缺点,这意味着可能有 1..10K 个对象,具体取决于它们的大小。不太明显的缺点是将新对象插入此类集合的成本将是巨大的:亚马逊指定将根据总项目大小扣除写入容量,而不仅仅是新添加的对象 - 因此约 400 个容量单位接近大小限制时插入 1KB 对象。那么考虑到这一点排除了吗?

  2. 使用复合主散列 + 范围键,其中主散列对于集合中的所有对象保持相同,范围键只是随机或原子计数器。明显的缺点是具有相同的哈希键会导致错误的键分布——当有大量对象的集合时基数很低。这意味着分区错误,并且存在规模问题,同一集合上的所有读/写都卡在一个分片上,受到 DynamoDB 分区每秒 3000 次读取/1000 次写入的限制。

  3. 使用带有二级哈希 + 范围键的全局二级索引,其中哈希键对于属于同一集合的所有对象保持相同,而范围键只是随机的或原子计数器。与上面类似,GSI 的分区变得很差,并且它将成为一个瓶颈,因为太多相同的哈希值会迅速耗尽所有预置容量到索引。我没有找到 GSI 是如何准确实现的,因此不确定它受低基数的影响有多严重。

问题是,我是否可以忍受 (2) 或 (3) 并遭受不理想的密钥分配,或者是否有另一种实现被忽视的集合的方式,或者我应该考虑研究另一个 nosql 数据库引擎。

4

1 回答 1

0

这是一个“从臀部射击”的答案,您最终会做什么可能取决于您阅读和写作的程度和类型。

dynamo 文档鼓励您避免的两件事是热键,通常是扫描。您注意到在情况 (2) 和 (3) 中,您最终会得到一个热键。如果您期望它可以扩展(大型集合),那么热键可能会受到越来越多的伤害,特别是如果这是一个写入密集型应用程序。

关于查询和扫描操作的文档 ( http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html ) 说,对于查询,“您必须将哈希键属性名称和值指定为平等条件。” 因此,如果您想避免扫描,这可能仍然会迫使您的手并让您回到那种热键情况。

也许一种方法是接受扫描操作,但只有一张表专门用于您的收藏。然后你可以只拥有一个完全随机(分布良好)的哈希键,并且每次都进行扫描。这假设您总是想要集合中的所有内容(您没有说)。如果你扩大到一个大的集合,这仍然会受到伤害,但如果你总是想要完整的集合,那么无论如何你都必须处理这种痛苦。如果你只想要一个子集,你可以添加一个限制参数。这将有助于提高性能,但您将始终返回相同的子集(或者您可以使用最后评估的密钥并继续前进)。文档还提到了并行扫描。

如果您使用 AWS,elasticache/redis 可能是另一种尝试?第一遍可能比您提到的情况(1)更快/更干净。

于 2015-09-21T18:50:03.820 回答