单个分区键值的DynamoDB最大分区大小是否为10GB?

时间:2016-10-26 21:44:25

标签: amazon-web-services amazon-dynamodb primary-key-design

我已经阅读了很多关于设计分区键和排序键的DynamoDB文档,但我认为我必须遗漏一些基本的东西。

如果您的分区键设计错误,当SINGLE分区键值的数据超过10GB时会发生什么?

“了解分区行为”部分说明:

“单个分区可容纳大约10 GB的数据”

如何分区单个分区密钥?

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html#GuidelinesForTables.Partitions

文档还讨论限制,本地二级索引限制为10GB数据,然后开始出错。

“任何项目集合的最大大小为10 GB。此限制不适用于没有本地二级索引的表;只有具有一个或多个本地二级索引的表才会受到影响。”

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html#LSI.ItemCollections

我能理解。如果它超过10GB,它还有一些其他的魔法来分割单个分区键的数据。或者只是继续增长分区?这对你的关键设计有什么影响?

问题的背景是我已经看到很多在TenantId环境中使用类似TenantId作为分区键的例子。但是,如果特定的TenantId可以拥有超过10 GB的数据,那似乎是有限的。

我一定错过了什么?

1 个答案:

答案 0 :(得分:15)

TL; DR - 通过将范围键值包含在分区函数中,即使它们具有相同的分区键值,也可以拆分项目。

长版:

这是一个非常好的问题,文档herehere已经解决了这个问题。如文档所述,DynamoDB表中的项目使用h ashing function基于其分区键值(以前称为哈希键)进行分区,分区为一个或多个分区。分区数是根据最大期望总吞吐量以及密钥空间中项目的分布得出的。换句话说,如果选择分区密钥使得它在分区密钥空间上均匀地分配项目,则分区最终具有大致相同数量的项目。每个分区中的项目数大约等于表中项目的总数除以分区数。

该文档还指出每个分区限制为大约10GB的空间。并且,一旦存储在任何分区中的所有项目的大小总和超过10GB,DynamoDB将启动后台进程,该进程将自动且透明地将这些分区分成两半 - 从而产生两个新分区。再一次,如果项目是统一分布的,这很好,因为每个新的子分区最终将占用原始分区中大约一半的项目。

拆分的一个重要方面是拆分分区的吞吐量每个都是原始分区可用吞吐量的一半。

到目前为止,我们已经涵盖了幸福的案例。

另一方面,可能有一个或几个分区键值对应于非常多的项目。如果表模式使用排序键并且多个项散列到同一分区键,则通常会发生这种情况。在这种情况下,单个分区键可能负责共同占用10 GB以上的项目。这将导致分裂。在这种情况下,DynamoDB仍然会创建两个新分区,但不是仅使用分区键来决定项目应存储在哪个子分区中,它也将使用排序键。

示例

不失一般性并且使事情更容易推理,想象有一个表格,其中分区键是字母(A-Z),数字用作排序键。

表格中有大约9个分区,因此字母A,B,C将存储在分区1中,字母D,E,F将存储在分区2中,等等。

在下图中,分区边界标记为h(A0)h(D0)等,以表明,例如,存储在第一个分区中的项目是分区键散列为值的项目在h(A0)h(D0)之间 - 0是有意的,接下来会派上用场。

[ h(A0) ]--------[ h(D0) ]---------[ h(G0) ]-------[ h(J0) ]-------[ h(M0) ]- ..
  |   A    B    C   |       E    F   |   G      I    |   J    K   L  |
  |   1    1    1   |       1    1   |   1      1    |   1    1   1  |
  |   2    2    2   |       2    2   |          2    |        2      |
  |   3         3   |            3   |          3    |               |
  ..                ..               ..              ..              ..
  |            100  |           500  |               |               |
  +-----------------+----------------+---------------+---------------+-- ..

请注意,对于大多数分区键值,表中有1到3个项目,但有两个分区键值:DF看起来不太好。 D有100件商品,而F有500件商品。

如果分区键值为F的项目不断添加,最终分区[h(D0)-h(G0))将被拆分。为了能够拆分具有相同散列键的项目,必须使用范围键值,因此我们最终会遇到以下情况:

..[ h(D0) ]------------/ [ h(F500) ] / ----------[ h(G0) ]- ..
      |       E       F       |           F         |
      |       1       1       |          501        |
      |       2       2       |          502        |
      |               3       |          503        |
      ..                      ..                    ..
      |              500      |         1000        |
.. ---+-----------------------+---------------------+--- ..

原始分区[h(D0)-h(G0))分为[h(D0)-h(F500))[h(F500)-h(G0))

我希望这有助于可视化项目通常根据通过对其分区键值应用散列函数获得的散列值映射到分区,但是如果需要,散列的值可以包括分区键+排序关键价值。