为什么我不应该在同一个分区键值中放置所有的DynamoDB项?

9

许多资源建议将高基数属性用作分区键。我的问题是,如果我反其道而行之,并给所有项目相同的分区键值(仅通过排序键进行区分),从而允许我在整个表上查询,会发生什么?

这会导致性能和/或热分区问题吗?如果自适应容量没有达到3000 RCUs/1000 WCUs,那么热分区是否重要?即使如此,如果我的排序键在查询中均匀分布,那又怎么样呢?

共识似乎是我们不应该这样做,但我的问题是:为什么不应该这样做?

3个回答

2
建议和最佳实践旨在指导您从使用DynamoDB中获得最大的收益。通常,人们使用DynamoDB来存储大量和高速数据,在传统关系型数据库中存在可扩展性问题。
如果您要处理的是少量数据,其中汇总访问速率不超过3000个RCU / 1000个WCUs,那么这对于您来说还不足以达到使用DynamoDB的痛点。实际上,如果您使用传统的关系型数据库,可能可以实现相同的性能水平。但是,一旦您的应用程序变得流行,甚至只是在5分钟的时间跨度内遇到了突发情况,数据量和速度就会迅速增加,您将感到痛苦。这就是为什么遵循最佳实践通常会给您带来这种未来的保证。
即使如此,如果我的排序键的查询均匀分布怎么办?
如果集合大小超过10 GB,则DynamoDB按排序键拆分分区。[ref]因此,您仍然可能会遇到热分区问题。
不要误解我的意思。有些情况下需要使用相同的分区键,比如对数据进行一对多和多对多关系建模。这些是有效的用例,因为数据本质上是关系型的,这是在DynamoDB中高效建模的唯一方法。然而,如果你选择完全违反文档建议的做法,你的可扩展性将受到限制,你将无法充分利用DynamoDB的优势。

1

好的,我们开始吧,我将会用一个示例应用程序来演示。

假设你正在为加拿大创建人口普查应用程序。你的分区键将是省份或地区名称,总共有13个(如果我没记错的话)。你加载初始数据,一切都很好。你让用户进来使用,一切都还好,但到了晚上,当每个人都回家并收到一张卡片,上面写着他们应该去你的网站时,问题就来了。那么加拿大的人口中心在哪里呢?安大略省和魁北克省人口最多,恰好位于同一个表分区中。糟糕了。是的,自适应容量会尝试拯救你,但很快就会有成千上万的人(或更多)试图使用你的网站。这个分区现在已经达到了每个分区3000 IOPS的配额,只有多伦多的一个部分在线。DynamoDB已经尝试将项目移动到其他分区并创建更多项目以拯救你的失误,但你的用户已经开始受到限制。你选择得不好。Twitter/reddit等社交媒体上现在充满了我不想引用的恶意评论。与此同时,拥有爱德华王子岛和育空地区的分区几乎没有什么活动。如果你选择了不同的分区键或使用省/地区名称进行写入分片,项目将更加均匀地分布,这将不会成为一个问题。

话虽如此,在另一种情况下,如果应用程序使用不频繁且主键的基数很低,则可能一切都很好。但随着应用程序的扩展,您的错误将变得明显。如果它永远不会扩展,那么可能没问题...但为什么要冒这个风险呢?

希望你能理解这个观点。此外,这种情况并不是 DynamoDB 才会出现的。我曾经使用过许多其他进行分区的数据库,其中也可能存在这样的问题。至少 DynamoDB 足够聪明,可以尝试随时间推移为您节省错误,但为什么要自找麻烦呢?


1

对于一个可扩展的应用程序,您不能假设其IOPS永远不会达到上限。由于流量从每个地区进入的方式都不相同,某些数据中心的流量可能比其他数据中心高得多。在某些特殊事件期间(例如,Alexa设备在圣诞节访问),预计将出现大量流量峰值,自适应容量需要在这种情况下产生影响,但具体延迟是不确定的,因此您需要提前规划扩展,并当然要尽量避免潜在的热分区问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接