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

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

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

由 Ramkumar Ramanujam 建立 (AWS)

環境:生產

來源:Amazon DynamoDB

目標:Amazon DynamoDB

R 類型:不適用

工作負載:所有其他工作負載

技術:資料庫

AWS 服務:Amazon DynamoDB

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服務時,請避免使用 IAM AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 使用者的 ,因為這些是長期憑證。請務必嘗試使用臨時憑證以程式設計方式存取 AWS 服務。

例如,開發人員在開發期間硬式編碼應用程式中IAM使用者的 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY ,但無法在將變更推送至程式碼儲存庫之前移除硬式編碼值。這些公開的憑證可以供非預期或惡意使用者使用,這可能會產生嚴重影響 (特別是當公開的憑證具有管理員權限時)。這些公開的憑證應該立即使用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 資料表。

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

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

在目標帳戶中建立具有存取 (建立、讀取、更新、刪除) 目標帳戶中 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 DynamoDB 用戶端將項目寫入目標帳戶中AWSSDK的資料表。 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和 4000WCUs。

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

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

附件

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