更改DynamoDB表的架构:最佳/推荐方式是什么?

时间:2015-07-08 18:47:00

标签: amazon-dynamodb

亚马逊推荐的在生产DynamoDB中更改大表模式的方法是什么?

想象一下假设的情况,我们有一个表Person,主哈希键SSN。该表可能包含1000万个项目。

现在有消息称,由于身份盗窃的严重程度,这个假想国家的政府已经引入了另一个个人身份识别:唯一个人识别码,或UPI。

我们必须添加一个UPI列并更改Person表的模式,以便现在主哈希键是UPI。 我们希望在一段时间内支持使用SSN的当前系统和使用UPI的新系统,因此我们需要这两个列在Person表中共存。

亚马逊推荐的这种架构更改方式是什么?

4 个答案:

答案 0 :(得分:21)

有两种方法,但首先您必须了解您无法更改现有表的架构。要获得不同的架构,您必须创建一个新表。您可以重用现有表,但结果与创建不同表的结果相同。

  1. 延迟迁移到同一个表,没有Streams。每次修改Person表中的条目时,使用UPI而不是SSN作为哈希键的值在Person表中创建一个新项,并删除在SSN键入的旧项。这假设UPI从不同于SSN的值范围中提取。如果SSN看起来像XXX-XX-XXXX,那么只要UPI具有与SSN不同的位数,那么您将永远不会有重叠。
  2. 使用Streams延迟迁移到同一个表。当流通常可用时,您将能够为您的Person表启用Stream。使用NEW_AND_OLD_IMAGES流视图类型创建流,并且每当您检测到对Person表中的现有人添加UPI的项的更改时,创建一个Lambda函数,该函数删除在SSN处键入的人并添加具有相同权限的人属于UPI的属性。此方法具有可通过向项添加原子计数器版本属性并在版本属性上调节DeleteItem调用来缓解竞争条件。
  3. 使用Streams抢占(脚本)迁移到其他表。运行扫描表的脚本,并为Person表中的每个Person项添加唯一的UPI。使用NEW_AND_OLD_IMAGES流视图类型在Person表上创建一个流,并为该流订阅一个lambda函数,当lambda函数检测到具有UPI的Person已更改或Person有一个人时,该函数将所有新人写入新的Person_UPI表中UPI补充道。基表上的突变通常需要数百毫秒才能作为流记录显示在流中,因此您可以对应用程序中的新Person_UPI表进行热故障转移。拒绝请求几秒钟,在此期间将应用程序指向Person_UPI表,然后重新启用请求。

答案 1 :(得分:11)

DynamoDB流使我们能够在不停机的情况下迁移表。我做得非常有效,我遵循的步骤是:

  1. 创建一个新表(让我们称之为NewTable),使用所需的密钥结构,LSI,GSI。
  2. 在原始表上启用DynamoDB Streams
  3. 将Lambda关联到Stream,将记录推送到NewT​​able。 (这个Lambda应该删除步骤5中的迁移标志)
  4. [可选]在原始表格上创建GSI以加快扫描项目。确保此GSI仅具有以下属性:主键和迁移(请参阅步骤5)。
  5. 扫描上一步(或整个表)中创建的GSI并使用以下过滤器:

    FilterExpression =" attribute_not_exists(已迁移)"

  6. 使用迁移标志更新表中的每个项目(即:“Migrated”:{“S”:“0”},将其发送到DynamoDB Streams(使用UpdateItem API,以确保不会发生数据丢失)。

    注意:您可能希望在更新期间增加表格上的写入容量单位。

    1. Lambda将获取所有项目,修剪Migrated标志并将其推入NewTable。
    2. 迁移完所有项目后,将代码重新指向新表格
    3. 删除原始表格,Lambda函数一旦开心就好了。
    4. 遵循这些步骤应确保您没有数据丢失且无停机时间。

      我已经在我的博客上记录了这一点,并提供了协助代码: https://www.abhayachauhan.com/2018/01/dynamodb-changing-table-schema/

答案 2 :(得分:2)

我使用亚历山大的第三种方法。再次,您创建一个新表,将在更新旧表时更新。不同之处在于,在您转换而不是使用lambda函数时,使用现有服务中的代码写入两个表。您可能拥有自己不希望在临时lambda函数中重现的自定义持久性代码,并且您可能无论如何都必须为此新表编写服务代码。根据您的架构,您甚至可以在没有停机的情况下切换到新表。

但是,使用lambda函数的好处是,对新表的附加写入引入的任何负载都将在lambda上,而不是服务上。

答案 3 :(得分:0)

如果更改涉及更改分区键,则可以添加新的GSI(全局二级索引)。此外,您始终可以向DynamoDB添加新的列/属性,而无需迁移表。