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

Mar*_*yly 13 primary-key-design amazon-web-services amazon-dynamodb

我已经阅读了很多关于设计分区键和排序键的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的数据,那似乎是有限的.

我肯定错过了什么?

Mik*_*scu 20

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


长版:

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

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

拆分的一个重要方面是拆分分区的吞吐量将分别是原始分区可用的吞吐量的一半.

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

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

在不失一般性并且易于推理的情况下,假设有一个表格,其中分区键是字母(AZ),并且数字用作排序键.

该表具有大约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  |               |               |
  +-----------------+----------------+---------------+---------------+-- ..
Run Code Online (Sandbox Code Playgroud)

请注意,对于大多数分区键值,表中有1到3个项目,但有两个分区键值:D并且F看起来不太好.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        |
.. ---+-----------------------+---------------------+--- ..
Run Code Online (Sandbox Code Playgroud)

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

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

  • 嗨@florins - 按照设计,在没有排序键的情况下,分区方案可确保数据在所有分区中的均匀分布。由于项目均匀分布,所有分区都被均匀填充,因此当发生拆分时,它们将跨所有分区发生。那有意义吗? (4认同)
  • 我不完全理解排序键是如何包含在哈希函数中的。如果我们这样做,具有连续排序键的元素可能会在不同的分区中结束。如果发生这种情况,我们将无法有效地回答查询。对? (3认同)
  • 虽然这是一个很好的答案,但它确实涵盖了最坏的情况,当您的偏斜数据只有分区键而没有排序键时。在这种情况下,拆分过程会发生什么? (2认同)