在不使用S3的情况下将DynamoDB表复制到另一个AWS账户

33

我想将所有DynamoDB表格复制到另一个AWS账户,但不使用S3来保存数据。我看到有通过数据管道复制带有数据的表格的解决方案,但是它们都使用S3来保存数据。由于表格包含大量数据,因此S3写入和读取过程可能需要时间,所以我想跳过S3步骤,直接从一个账户复制表格到另一个账户。

6个回答

58

如果您不介意使用Python,并添加boto3库(sudo python -m pip install boto3),那么我会这样做(假设您知道如何在代码中分别填充密钥、区域和表名称):

import boto3
import os

dynamoclient = boto3.client('dynamodb', region_name='eu-west-1',
    aws_access_key_id='ACCESS_KEY_SOURCE',
    aws_secret_access_key='SECRET_KEY_SOURCE')

dynamotargetclient = boto3.client('dynamodb', region_name='us-west-1',
    aws_access_key_id='ACCESS_KEY_TARGET',
    aws_secret_access_key='SECRET_KEY_TARGET')

dynamopaginator = dynamoclient.get_paginator('scan')
tabname='SOURCE_TABLE_NAME'
targettabname='TARGET_TABLE_NAME'
dynamoresponse = dynamopaginator.paginate(
    TableName=tabname,
    Select='ALL_ATTRIBUTES',
    ReturnConsumedCapacity='NONE',
    ConsistentRead=True
)
for page in dynamoresponse:
    for item in page['Items']:
        dynamotargetclient.put_item(
            TableName=targettabname,
            Item=item
        )

3
运作得很好。请注意,此脚本需要目标表已经存在。 - Pupper
1
回来这里点赞和评论。这太棒了。 - Pranav Nandan
仅供记录,使用代码中的秘密和访问密钥并不是最佳实践,而是使用IAM角色。可以在以下链接中找到如何在不同帐户之间使用IAM角色的方法:https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html - GorkemHalulu
2
@GorkemHalulu 我同意,从上下文中我理解这只是一次性的,而不是一个实际的应用程序。我非常确定没有一个理智的人会将他们的秘密密钥提交到公共仓库中。我会使用机器角色来重写它,但是迄今为止我的答案还没有被接受,所以我不在乎;) - Adam Owczarczyk
2
我重新设计了这个程序,使其能够扮演不同的角色,并将参数存储在环境变量中。如果有人需要,我已经将它放在了这个代码库中: https://gitlab.com/archetypalsxe/dynamodb-importer - ET Come Back
@ETComeBack 你可以把它发布为答案。GitLab 打开太慢了 :( - RNA

24

试试这个nodejs模块

npm i copy-dynamodb-table

这是最好的 - 如此简单。 - Ray Jennings
这应该是被接受的答案。非常好用。 - atlantis
但它可以在两个账户之间复制吗?README 文档没有明确说明... - Niklas Rosencrantz
@NiklasRosencrantz 是的,它可以在账户之间复制! - Ben Romberg

8
使用boto进行Amazon DynamoDB的简单备份和还原
您可以使用以下工具:https://github.com/bchew/dynamodump 它可以执行以下操作:
  • 单表备份/还原
  • 多表备份/还原
  • 多表备份/还原,但在不同的环境之间(例如将production-*表备份到development-*表)
  • 备份所有表并仅还原数据(不会删除和重新创建模式)
  • 转储所有表模式并创建模式(例如在不同的AWS帐户中创建空表)
  • 基于AWS标签键=值备份所有表
  • 基于AWS标签备份所有表,压缩并存储在指定的S3存储桶中。
  • 从S3存储桶还原到指定的目标表

这个答案可以通过一些备份和恢复数据库命令的使用示例来改进。 - Shadow Man
实际上,我最终创建了自己的Bash脚本,它可以执行以下操作:1)在表格、区域和账户之间复制数据库,2)将数据库转换为JSON格式,3)将JSON转换回数据库。 - RNA

3
读写S3不会成为瓶颈。虽然从Dynamo扫描会非常快,但将项目写入目标表会很慢。每个分区每秒只能写入最多1000个项目。因此,我不会担心中间的S3存储。然而,数据管道也不是将表复制到另一个表的最有效方法。如果您需要快速传输,则最好实现自己的解决方案。根据所需的传输吞吐量配置目标表(但要注意不希望的分区拆分),然后编写使用多个线程的并行扫描,该扫描还将写入目标表。在AWS实验室存储库中有一个Java的开放源代码实现,可用作起点。 https://github.com/awslabs/dynamodb-cross-region-library

1
您可以使用deepcopy和dynamodb_json:
import boto3
import json
from dynamodb_json import json_util as djson 
from copy import deepcopy
REGION = 'eu-west-1'

# init your sessions to the different accounts (session_a and session_b)   

dynamo_a = session_a.client('dynamodb', region_name=REGION)
dynamo_b = session_b.resource('dynamodb', region_name=REGION)

table = dynamo_b.Table('abc')
result_data = table.scan()
result_item = []
result_item.extend(result_data['Items'])
while 'LastEvaluatedKey' in result_data:
    result_data = my_table.scan(
        FilterExpression=filter_expression,
        ExclusiveStartKey=result_data['LastEvaluatedKey']
    )

    result_item.extend(result_data['Items'])

translated_items = []
for r in result_item:
    updated_item = deepcopy(r)
    translated_items.append(updated_item)

for r in translated_items:
    item = json.loads(djson.dumps(r))
    dynamo_a.put_item(TableName='def', Item=item)

0

S3绝对不是瓶颈。 我几乎可以说,对于99%的用例,您应该使用AWS建议的最佳实践“Data Pipeline + S3”进行操作。 我在这里提供了更详细的答案:https://dev59.com/fqzka4cB1Zd3GeqP72Wk#57465721

真正的问题是,您是否组织其他系统和客户端以实时读取/写入数据的方式进行迁移,而不会导致停机时间。 如果这是您对任务时间表最担心的问题-那么您需要设计自定义解决方案,以确保所有写入都进入两个帐户中的DDB表,并将读取数据的客户端切换到目标DDB表,然后再最终切换写入数据的客户端。 也有一些其他类型的迁移计划可供选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接