我正在研究在Amazon DynamoDB之上实现可扩展的无序对象集合。到目前为止,已经考虑了以下选项:
使用DynamoDB文档数据类型(映射,列表)并使用文档路径访问独立项。这有一个明显的缺点,收集限制为400KB的数据,这意味着可能是1..10K对象,具体取决于它们的大小。不太明显的缺点是,将新对象插入此类集合的成本将是巨大的:亚马逊规定将根据总项目大小扣除写入容量,而不仅仅是新添加的对象 - 因此约400个容量单位在接近大小限制时插入1KB对象。所以考虑到这个被排除了吗?
使用复合主哈希+范围键,其中主哈希对于集合中的所有对象保持相同,范围键只是随机或原子计数器。明显的缺点是具有相同的散列键会导致错误的密钥分发 - 当存在具有大量对象的集合时,基数很低。这意味着分区错误,并且同一个集合上的所有读/写都存在一个规模问题,这个分支会粘在一个分片上,每秒受3000次读取/ 1000次写入限制DynamoDB分区。
将全局二级索引与二级哈希+范围键一起使用,其中哈希键对于属于同一集合的所有对象保持相同,并且范围键只是随机或原子计数器。与上面类似,GSI的分区变得很差,并且它将成为一个瓶颈,太多相同的哈希值迅速耗尽了索引的所有配置容量。我没有找到GSI是如何完全实现的,因此不确定它在低基数方面有多么糟糕。
问题是,我是否可以忍受(2)或(3)并且遭受非理想的密钥分发,或者是否有另一种实现被忽略的集合的方式,或者我应该考虑考虑另一个nosql数据库引擎。
答案 0 :(得分:0)
这是一个“嘻嘻哈哈”的回答,你最终做的可能取决于你做多少和什么类型的阅读和写作。
发电机文档鼓励您避免的两件事是热键,一般来说,扫描。您注意到在情况(2)和(3)中,您最终得到了一个热键。如果您希望扩展(大型集合),热键可能会受到越来越多的伤害,特别是如果这是一个写密集型应用程序。
有关查询和扫描操作(http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html)的文档说,对于查询,“必须将哈希键属性名称和值指定为相等条件”。因此,如果您想避免扫描,这可能仍然会迫使您的手回到热键情况。
也许有一条路线可以包含进行扫描操作,但只有一个表专门用于您的收藏。然后你可以拥有一个完全随机(分布均匀)的哈希键,并且每次都进行扫描。这假设您总是想要收集的所有内容(您没有说)。如果你扩展到一个大的集合,这仍然会受到伤害,但如果你总是想要完整的集合,你将不得不处理这种痛苦。如果您只想要一个子集,可以添加一个limit参数。这将有助于提高性能,但您将始终返回相同的子集(或者您可以使用最后评估的密钥并继续)。文档还提到了并行扫描。
如果您使用的是AWS,可以尝试使用elasticache / redis吗?第一遍可能比你提到的情况(1)更快/更清晰地编码。