

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用自訂實作跨帳戶複製 Amazon DynamoDB 資料表
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation"></a>

*Ramkumar Ramanujam，Amazon Web Services*

## 總結
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-summary"></a>

在 Amazon Web Services (AWS) 上使用 Amazon DynamoDB 時，常見的使用案例是將開發、測試或預備環境中的 DynamoDB 資料表與生產環境中的資料表資料進行複製或同步。根據標準實務，每個環境都使用不同的 AWS 帳戶。

DynamoDB 現在支援使用 AWS Backup 的跨帳戶備份。如需使用 AWS Backup 時相關儲存成本的資訊，請參閱 [AWS Backup 定價](https://aws.amazon.com/backup/pricing/)。當您使用 AWS Backup 跨帳戶複製時，來源和目標帳戶必須是 AWS Organizations 組織的一部分。還有其他使用 AWS Glue 等 AWS 服務進行跨帳戶備份和還原的解決方案。不過，使用這些解決方案會增加應用程式足跡，因為要部署和維護的 AWS 服務更多。 

您也可以使用 Amazon DynamoDB Streams 擷取來源帳戶中的資料表變更。然後，您可以啟動 AWS Lambda 函數，並在目標帳戶中的目標資料表中進行對應的變更。但是，該解決方案適用於來源和目標資料表必須保持同步的使用案例。它可能不適用於頻繁更新資料的開發、測試和預備環境。

此模式提供實作自訂解決方案的步驟，將 Amazon DynamoDB 資料表從一個帳戶複製到另一個帳戶。此模式可以使用常見的程式設計語言實作，例如 C\$1、Java 和 Python。建議使用 [AWS 開發套件](https://aws.amazon.com/tools/)支援的語言。

## 先決條件和限制
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-prereqs"></a>

**先決條件**
+ 兩個作用中的 AWS 帳戶
+ 兩個帳戶中的 DynamoDB 資料表
+ 了解 AWS Identity and Access Management (IAM) 角色和政策
+ 了解如何使用任何常見的程式設計語言存取 Amazon DynamoDB 資料表，例如 C\$1、Java 或 Python

**限制**

此模式適用於大約 2 GB 或更小的 DynamoDB 資料表。透過額外的邏輯來處理連線或工作階段中斷、限流、故障和重試，它可用於較大的資料表。

DynamoDB 掃描操作會從來源資料表讀取項目，在單一呼叫中最多只能擷取 1 MB 的資料。對於大於 2 GB 的較大資料表，此限制可能會增加執行完整資料表複本的總時間。

## Architecture
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-architecture"></a>

下圖顯示來源和目標 AWS 帳戶之間的自訂實作。IAM 政策和安全字符會與自訂實作搭配使用。從來源帳戶中的 Amazon DynamoDB 讀取資料，並寫入目標帳戶中的 DynamoDB。

![\[使用自訂實作複製的來源和目標帳戶架構。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/ba8175be-9809-4c2e-b2d1-6b9180ed056c/images/d9d4c2c8-ff04-443f-9137-e37b8e23ccb5.png)


 

**自動化和擴展**

此模式適用於大小較小的 DynamoDB 資料表，約為 2 GB。 

若要將此模式套用至較大的資料表，請解決下列問題：
+ 在資料表複製操作期間，會使用不同的安全字符來維護兩個作用中工作階段。如果資料表複製操作花費的時間超過字符過期時間，您必須設定邏輯來重新整理安全字符。 
+ 如果未佈建足夠的讀取容量單位 RCUs) 和寫入容量單位 WCUs)，則來源或目標資料表上的讀取或寫入可能會受到調節。請務必擷取並處理這些例外狀況。 
+ 處理任何其他失敗或例外狀況，並設定重試機制，以便在複製操作失敗時重試或繼續。

## 工具
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-tools"></a>

**工具**
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) – Amazon DynamoDB 是全受管的 NoSQL 資料庫服務，可提供快速且可預測的效能和無縫的可擴展性。 
+ 所需的其他工具會根據您為實作選擇的程式設計語言而有所不同。例如，如果您使用 C\$1，您將需要 Microsoft Visual Studio 和下列 NuGet 套件：
  + `AWSSDK`
  + `AWSSDK.DynamoDBv2`

**Code**

下列 Python 程式碼片段會使用 Boto3 程式庫刪除並重新建立 DynamoDB 資料表。

請勿使用 `AWS_SECRET_ACCESS_KEY` IAM 使用者的 `AWS_ACCESS_KEY_ID`和 ，因為這些是長期登入資料，因此應該避免以程式設計方式存取 AWS 服務。如需暫時登入資料的詳細資訊，請參閱*最佳實務*一節。

下列程式碼片段`TEMPORARY_SESSION_TOKEN`中使用的 `AWS_ACCESS_KEY_ID``AWS_SECRET_ACCESS_KEY`、 和 是從 AWS Security Token Service (AWS STS) 擷取的暫時登入資料。

```
import boto3
import sys
import json

#args = input-parameters = GLOBAL_SEC_INDEXES_JSON_COLLECTION, ATTRIBUTES_JSON_COLLECTION, TARGET_DYNAMODB_NAME, TARGET_REGION, ...

#Input param: GLOBAL_SEC_INDEXES_JSON_COLLECTION
#[{"IndexName":"Test-index","KeySchema":[{"AttributeName":"AppId","KeyType":"HASH"},{"AttributeName":"AppType","KeyType":"RANGE"}],"Projection":{"ProjectionType":"INCLUDE","NonKeyAttributes":["PK","SK","OwnerName","AppVersion"]}}]

#Input param: ATTRIBUTES_JSON_COLLECTION
#[{"AttributeName":"PK","AttributeType":"S"},{"AttributeName":"SK","AttributeType":"S"},{"AttributeName":"AppId","AttributeType":"S"},{"AttributeName":"AppType","AttributeType":"N"}]

region = args['TARGET_REGION']
target_ddb_name = args['TARGET_DYNAMODB_NAME']

global_secondary_indexes = json.loads(args['GLOBAL_SEC_INDEXES_JSON_COLLECTION'])
attribute_definitions = json.loads(args['ATTRIBUTES_JSON_COLLECTION'])

# Drop and create target DynamoDB table
dynamodb_client = boto3.Session(
        aws_access_key_id=args['AWS_ACCESS_KEY_ID'],
        aws_secret_access_key=args['AWS_SECRET_ACCESS_KEY'],
        aws_session_token=args['TEMPORARY_SESSION_TOKEN'],
    ).client('dynamodb')
    
# Delete table
print('Deleting table: ' + target_ddb_name + ' ...')

try:
    dynamodb_client.delete_table(TableName=target_ddb_name)

    #Wait for table deletion to complete
    waiter = dynamodb_client.get_waiter('table_not_exists')
    waiter.wait(TableName=target_ddb_name)
    print('Table deleted.')
except dynamodb_client.exceptions.ResourceNotFoundException:
    print('Table already deleted / does not exist.')
    pass

print('Creating table: ' + target_ddb_name + ' ...')

table = dynamodb_client.create_table(
    TableName=target_ddb_name,
    KeySchema=[
        {
            'AttributeName': 'PK',
            'KeyType': 'HASH'  # Partition key
        },
        {
            'AttributeName': 'SK',
            'KeyType': 'RANGE'  # Sort key
        }
    ],
    AttributeDefinitions=attribute_definitions,
    GlobalSecondaryIndexes=global_secondary_indexes,
    BillingMode='PAY_PER_REQUEST'
)
    
waiter = dynamodb_client.get_waiter('table_exists')
waiter.wait(TableName=target_ddb_name)
    
print('Table created.')
```

## 最佳實務
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-best-practices"></a>

**臨時憑證**

作為安全最佳實務，以程式設計方式存取 AWS 服務時，請避免使用 `AWS_SECRET_ACCESS_KEY` IAM 使用者的 `AWS_ACCESS_KEY_ID`和 ，因為這些是長期憑證。一律嘗試使用臨時登入資料，以程式設計方式存取 AWS 服務。

例如，開發人員會在開發期間硬式編碼應用程式中 `AWS_SECRET_ACCESS_KEY` IAM 使用者的 `AWS_ACCESS_KEY_ID`和 ，但無法在將變更推送至程式碼儲存庫之前移除硬式編碼值。這些公開的登入資料可供非預期或惡意使用者使用，這可能會產生嚴重影響 （特別是當公開的登入資料具有管理員權限時）。這些公開的登入資料應該使用 IAM 主控台或 AWS Command Line Interface (AWS CLI) 立即停用或刪除。

若要取得以程式設計方式存取 AWS 服務的臨時登入資料，請使用 AWS STS。暫時登入資料僅在指定的時間內有效 （從 15 分鐘到 36 小時）。臨時登入資料的允許持續時間上限會根據角色設定和角色鏈結等因素而有所不同。如需 AWS STS 的詳細資訊，請參閱 [文件](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)。

## 史詩
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-epics"></a>

### 設定 DynamoDB 資料表
<a name="set-up-dynamodb-tables"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立 DynamoDB 資料表。 | 在來源和目標 AWS 帳戶中建立具有索引的 DynamoDB 資料表。將容量佈建設定為隨需模式，這可讓 DynamoDB 根據工作負載動態擴展讀取/寫入容量。 或者，您可以使用佈建容量搭配 4000 RCUs 和 4000 WCUs。 | 應用程式開發人員、DBA、遷移工程師 | 
| 填入來源資料表。 | 使用測試資料填入來源帳戶中的 DynamoDB 資料表。擁有至少 50 MB 或更多的測試資料可協助您查看資料表複製期間消耗的峰值和平均 RCUs。然後，您可以視需要變更容量佈建。 | 應用程式開發人員、DBA、遷移工程師 | 

### 設定登入資料以存取 DynamoDB 資料表
<a name="set-up-credentials-to-access-the-dynamodb-tables"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立 IAM 角色以存取來源和目標 DynamoDB 資料表。 | 在來源帳戶中建立具有存取 （讀取） 來源帳戶中 DynamoDB 資料表許可的 IAM 角色。新增來源帳戶做為此角色的信任實體。在目標帳戶中建立具有存取 （建立、讀取、更新、刪除） 目標帳戶中 DynamoDB 資料表許可的 IAM 角色。 新增目標帳戶做為此角色的信任實體。 | 應用程式開發人員、AWS DevOps | 

### 將資料表資料從一個帳戶複製到另一個帳戶
<a name="copy-table-data-from-one-account-to-another"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 取得 IAM 角色的臨時登入資料。 | 取得來源帳戶中建立之 IAM 角色的臨時登入資料。取得在目標帳戶中建立之 IAM 角色的臨時登入資料。取得 IAM 角色臨時登入資料的一種方法是從 AWS CLI 使用 AWS STS。<pre>aws sts assume-role --role-arn arn:aws:iam::<account-id>:role/<role-name> --role-session-name <session-name> --profile <profile-name></pre>使用適當的 AWS 設定檔 （對應至來源或目標帳戶）。如需取得臨時登入資料之不同方式的詳細資訊，請參閱下列內容：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation.html) | 應用程式開發人員、遷移工程師 | 
| 初始化來源和目標 DynamoDB 存取的 DynamoDB 用戶端。 | 針對來源和目標 DynamoDB 資料表初始化 AWS 開發套件提供的 DynamoDB 用戶端。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation.html)如需使用 IAM 臨時登入資料提出請求的詳細資訊，請參閱 [AWS 文件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/AuthUsingTempSessionToken.html)。 | 應用程式開發人員 | 
| 捨棄並重新建立目標資料表。 | 使用目標帳戶 DynamoDB 用戶端，在目標帳戶中刪除並重新建立目標 DynamoDB 資料表 （以及索引）。從 DynamoDB 資料表刪除所有記錄是一項昂貴的操作，因為它會使用佈建WCUs。刪除和重新建立資料表可避免這些額外費用。您可以在建立索引後將索引新增至資料表，但這需要 2-5 分鐘的時間。透過將索引集合傳遞至`createTable`呼叫，在資料表建立期間建立索引更有效率。 | 應用程式開發人員 | 
| 執行資料表複製。 | 重複下列步驟，直到複製所有資料：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation.html)如需詳細資訊，請參閱*附件*區段中的 C\$1 中的參考實作 （適用於捨棄、建立和填入資料表）。也會連接範例資料表組態 JavaScript 物件標記法 (JSON) 檔案。 | 應用程式開發人員 | 

## 相關資源
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-resources"></a>
+ [Amazon DynamoDB 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html)
+ [在 AWS 帳戶中建立 IAM 使用者](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)
+ [AWS 開發套件](https://aws.amazon.com/tools/)
+ [搭配 AWS 資源使用臨時登入資料](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)

## 其他資訊
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-additional"></a>

此模式使用 C\$1 實作，以複製具有 200，000 個項目的 DynamoDB 資料表 （平均項目大小為 5 KB，資料表大小為 250 MB)。目標 DynamoDB 資料表的設定佈建容量為 4000 RCUs 和 4000 WCUs。

完整的資料表複製操作 （從來源帳戶到目標帳戶），包括捨棄和重新建立資料表，需要 5 分鐘。使用的總容量單位：30，000 RCUs 和大約 400，000 WCUs。

如需 DynamoDB 容量模式的詳細資訊，請參閱 AWS 文件中的[讀取/寫入容量模式](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html)。

## 附件
<a name="attachments-ba8175be-9809-4c2e-b2d1-6b9180ed056c"></a>

若要存取與本文件相關聯的其他內容，請解壓縮下列檔案： [attachment.zip](samples/p-attach/ba8175be-9809-4c2e-b2d1-6b9180ed056c/attachments/attachment.zip)