有许多资源建议将高基数属性用作分区键。我的问题是,如果我反其道而行之,并给所有项目相同的分区键值(仅通过排序键进行区分),从而允许我在整个表上查询,会发生什么?
这会导致性能和/或热分区问题吗?如果自适应容量没有达到3000 RCUs/1000 WCUs,那么热分区是否重要?即使如此,如果我的排序键在查询中均匀分布,那又怎么样呢?
共识似乎是我们不应该这样做,但我的问题是:为什么不应该这样做?
有许多资源建议将高基数属性用作分区键。我的问题是,如果我反其道而行之,并给所有项目相同的分区键值(仅通过排序键进行区分),从而允许我在整个表上查询,会发生什么?
这会导致性能和/或热分区问题吗?如果自适应容量没有达到3000 RCUs/1000 WCUs,那么热分区是否重要?即使如此,如果我的排序键在查询中均匀分布,那又怎么样呢?
共识似乎是我们不应该这样做,但我的问题是:为什么不应该这样做?
好的,我们开始吧,我将会用一个示例应用程序来演示。
假设你正在为加拿大创建人口普查应用程序。你的分区键将是省份或地区名称,总共有13个(如果我没记错的话)。你加载初始数据,一切都很好。你让用户进来使用,一切都还好,但到了晚上,当每个人都回家并收到一张卡片,上面写着他们应该去你的网站时,问题就来了。那么加拿大的人口中心在哪里呢?安大略省和魁北克省人口最多,恰好位于同一个表分区中。糟糕了。是的,自适应容量会尝试拯救你,但很快就会有成千上万的人(或更多)试图使用你的网站。这个分区现在已经达到了每个分区3000 IOPS的配额,只有多伦多的一个部分在线。DynamoDB已经尝试将项目移动到其他分区并创建更多项目以拯救你的失误,但你的用户已经开始受到限制。你选择得不好。Twitter/reddit等社交媒体上现在充满了我不想引用的恶意评论。与此同时,拥有爱德华王子岛和育空地区的分区几乎没有什么活动。如果你选择了不同的分区键或使用省/地区名称进行写入分片,项目将更加均匀地分布,这将不会成为一个问题。话虽如此,在另一种情况下,如果应用程序使用不频繁且主键的基数很低,则可能一切都很好。但随着应用程序的扩展,您的错误将变得明显。如果它永远不会扩展,那么可能没问题...但为什么要冒这个风险呢?
希望你能理解这个观点。此外,这种情况并不是 DynamoDB 才会出现的。我曾经使用过许多其他进行分区的数据库,其中也可能存在这样的问题。至少 DynamoDB 足够聪明,可以尝试随时间推移为您节省错误,但为什么要自找麻烦呢?
对于一个可扩展的应用程序,您不能假设其IOPS永远不会达到上限。由于流量从每个地区进入的方式都不相同,某些数据中心的流量可能比其他数据中心高得多。在某些特殊事件期间(例如,Alexa设备在圣诞节访问),预计将出现大量流量峰值,自适应容量需要在这种情况下产生影响,但具体延迟是不确定的,因此您需要提前规划扩展,并当然要尽量避免潜在的热分区问题。