31

我已经阅读了很多关于设计分区键和排序键的 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 可以拥有超过 10 GB 的数据,这似乎会受到限制。

我肯定错过了什么?

4

1 回答 1

47

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


长版:

这是一个很好的问题,在此处此处的文档中都有说明。如文档所述,DynamoDB 表中的项目使用 ah ashing 函数根据其分区键值(以前称为hash key)划分为一个或多个分区. 分区的数量是根据最大期望总吞吐量以及键空间中项目的分布得出的。换句话说,如果选择分区键以使其在分区键空间中均匀分布项目,则每个分区最终具有大致相同数量的项目。每个分区中的项目数大约等于表中的项目总数除以分区数。

该文档还指出,每个分区的空间限制为大约 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  |               |               |
  +-----------------+----------------+---------------+---------------+-- ..

请注意,对于大多数分区键值,表中有 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        |
.. ---+-----------------------+---------------------+--- ..

原来的分区[h(D0)-h(G0))被分割成[h(D0)-h(F500))[h(F500)-h(G0))

我希望这有助于可视化项目通常基于通过将散列函数应用于其分区键值而获得的散列值映射到分区,但如果需要,被散列的值可以包括分区键 + 排序键值出色地。

于 2016-10-27T06:00:53.097 回答