使用自訂實作將 Amazon DynamoDB 資料表跨帳戶複製 - AWS 方案指引

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

使用自訂實作將 Amazon DynamoDB 資料表跨帳戶複製

由 Ramkumar Ramanujam 建立 (AWS)

Summary

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

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

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

此模式提供實作自訂解決方案的步驟,將 Amazon DynamoDB 資料表從一個帳戶複製到另一個帳戶。此模式可以使用常見的程式設計語言實作,例如 C#、Java 和 Python。建議使用 AWS SDK支援的語言。

先決條件和限制

先決條件

  • 兩個作用中AWS帳戶

  • 兩個帳戶中的 DynamoDB 資料表

  • 了解 AWS Identity and Access Management (IAM) 角色和政策

  • 了解如何使用任何常見的程式設計語言存取 Amazon DynamoDB 資料表,例如 C#、Java 或 Python

限制

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

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

架構

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

使用自訂實作複製的來源和目標帳戶架構。

自動化和擴展

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

若要將此模式套用至較大的資料表,請解決下列問題:

  • 在資料表複製操作期間,會使用不同的安全字符來維護兩個作用中工作階段。如果資料表複製操作花費的時間超過字符過期時間,您必須設定邏輯來重新整理安全字符。 

  • 如果未佈建足夠的讀取容量單位 (RCUs) 和寫入容量單位 (WCUs),來源或目標資料表上的讀取或寫入可能會受到調節。請務必擷取並處理這些例外狀況。 

  • 處理任何其他失敗或例外狀況,並設定重試機制,以便在複製操作失敗時重試或繼續操作。

工具

工具

  • Amazon DynamoDB – Amazon DynamoDB 是完全受管的無SQL資料庫服務,可提供快速且可預測的效能,並具有無縫的可擴展性。 

  • 所需的其他工具會根據您為實作選擇的程式設計語言而有所不同。例如,如果您使用 C#,您將需要 Microsoft Visual Studio 和下列 NuGet 套件:

    • AWSSDK

    • AWSSDK.DynamoDBv2

Code

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

請勿使用 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY IAM使用者的 ,因為這些是長期登入資料,應該避免用於以程式設計方式存取 AWS 服務。如需臨時登入資料的詳細資訊,請參閱最佳實務一節。

下列程式碼片段TEMPORARY_SESSION_TOKEN中使用的 AWS_SECRET_ACCESS_KEYAWS_ACCESS_KEY_ID和 是擷取自 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.')

最佳實務

暫時性憑證

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

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

若要取得以程式設計方式存取 AWS服務的臨時登入資料,請使用 AWS STS。暫時登入資料僅在指定的時間內有效 (從 15 分鐘到 36 小時)。臨時登入資料的允許持續時間上限取決於角色設定和角色鏈結等因素。如需 AWS 的詳細資訊STS,請參閱 文件

史詩

任務描述所需的技能

建立 DynamoDB 資料表。

在來源和目標AWS帳戶中建立具有索引的 DynamoDB 資料表。

將容量佈建設定為隨需模式,這可讓 DynamoDB 根據工作負載動態擴展讀取/寫入容量。 

或者,您可以使用佈建容量搭配 4000 RCUs和 4000 WCUs。

應用程式開發人員、DBA、遷移工程師

填入來源資料表。

使用測試資料填入來源帳戶中的 DynamoDB 資料表。至少有 50 MB 以上的測試資料可協助您查看資料表複製期間RCUs消耗的峰值和平均數。然後,您可以視需要變更容量佈建。

應用程式開發人員、DBA、遷移工程師
任務描述所需的技能

建立 IAM角色以存取來源和目標 DynamoDB 資料表。

在來源帳戶中建立具有存取 (讀取) 來源帳戶中 DynamoDB 資料表許可IAM的角色。

新增來源帳戶做為此角色的信任實體。

在目標帳戶中建立具有存取 (建立、讀取、更新、刪除) 目標帳戶中 DynamoDB 資料表許可IAM的角色。 

新增目標帳戶做為此角色的信任實體。

應用程式開發人員、 AWS DevOps
任務描述所需的技能

取得IAM角色的暫時登入資料。

取得在來源帳戶中建立之IAM角色的暫時登入資料。

取得在目標帳戶中建立之IAM角色的臨時登入資料。

取得IAM角色臨時登入資料的其中一個方法是AWSSTS從 使用 AWS CLI。

aws sts assume-role --role-arn arn:aws:iam::<account-id>:role/<role-name> --role-session-name <session-name> --profile <profile-name>

使用適當的AWS設定檔 (對應至來源或目標帳戶)。

如需取得臨時登入資料之不同方式的詳細資訊,請參閱下列內容:

應用程式開發人員、遷移工程師

初始化來源和目標 DynamoDB 存取的 DynamoDB 用戶端。

初始化來源和目標 DynamoDB 資料表的 DynamoDB 用戶端SDK,由 AWS 提供。

  • 對於來源 DynamoDB 用戶端,請使用從來源帳戶擷取的暫時憑證。

  • 對於目標 DynamoDB 用戶端,請使用從目標帳戶擷取的暫時登入資料。

如需使用IAM暫時登入資料提出請求的詳細資訊,請參閱 AWS 文件

應用程式開發人員

捨棄並重新建立目標資料表。

使用目標帳戶 DynamoDB 用戶端,在目標帳戶中刪除並重新建立目標 DynamoDB 資料表 (以及索引)。

從 DynamoDB 資料表刪除所有記錄是一項昂貴的操作,因為它使用佈建的 WCUs。刪除和重新建立資料表可避免這些額外費用。

您可以在建立索引之後,將索引新增至資料表,但這需要 2 到 5 分鐘的時間。透過將索引集合傳遞至createTable呼叫,在建立資料表期間建立索引更有效率。

應用程式開發人員

執行資料表複製。

重複下列步驟,直到複製所有資料:

  • 使用來源 DynamoDB 用戶端,對來源帳戶中的資料表執行掃描。每個 DynamoDB 掃描只會從資料表擷取 1 MB 的資料,因此您必須重複此操作,直到讀取所有項目或記錄為止。

  • 對於每組掃描的項目,使用 DynamoDB 的 呼叫,使用目標 DynamoDB 用戶端將項目寫入目標帳戶中AWSSDK的資料表 DynamoDB 。 BatchWriteItem這可減少對 DynamoDB 提出的PutItem請求數量。 

  • BatchWriteItem 具有 25 個寫入或放置的限制,或高達 16 MB。呼叫 之前,您必須新增邏輯,以計數 25 累積掃描的項目BatchWriteItem。 會BatchWriteItem傳回無法成功複製的項目清單。使用此清單,新增重試邏輯,以僅對未成功的項目執行另一個BatchWriteItem呼叫。

如需詳細資訊,請參閱附件區段中的 C# 中的參考實作 (適用於捨棄、建立和填入資料表)。也會連接範例資料表組態 JavaScript 物件標記 (JSON) 檔案。

應用程式開發人員

相關資源

其他資訊

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

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

如需 DynamoDB 容量模式的詳細資訊,請參閱 AWS 文件中的讀取/寫入容量模式

附件

若要存取與本文件相關聯的其他內容,請解壓縮下列檔案: attachment.zip