여러 Amazon DynamoDB 테이블의 용량 모드를 동시에 변경하려면 어떻게 해야 합니까?
여러 Amazon DynamoDB 테이블의 용량 모드를 동시에 변경하고 싶습니다.
간략한 설명
여러 DynamoDB 테이블의 용량 모드를 변경할 때 프로비저닝된 용량 모드 또는 온디맨드 용량 모드를 지정해야 합니다. 용량 모드를 변경하기 전에 DynamoDB에서 용량 모드 전환 시 고려 사항을 참조하십시오.
여러 DynamoDB 테이블의 용량 모드를 동시에 변경하려면 다음 방법 중 하나를 사용하십시오.
- AWS Command Line Interface(AWS CLI)
- AWS CloudFormation
- Python
해결 방법
모범 사례
여러 DynamoDB 테이블의 용량 모드를 변경하는 경우 다음 모범 사례를 사용하십시오.
- 변경을 시작하기 전에 적절한 AWS CLI 자격 증명을 구성하십시오.
- 적절한 AWS Identity and Access Management(IAM) 권한이 있는지 확인하십시오.
- 먼저 비프로덕션 환경에 변경 사항을 배포하십시오.
- 각 테이블에서 전환이 완료될 때까지 몇 분 정도 기다리십시오.
- 각 테이블에 대해 24시간마다 한 번만 용량 모드를 전환하십시오.
- 사용 패턴을 분석하여 적절한 용량 모드를 선택하고, AWS 리전 요구 사항에 맞게 조정하십시오.
- 전환 후 비용을 모니터링하여 프로비저닝된 용량이 적절한지 확인하십시오.
AWS CLI
참고: AWS Command Line Interface(AWS CLI) 명령을 실행할 때 오류가 발생하면 AWS CLI의 오류 해결을 참조하십시오. 또한 최신 AWS CLI 버전을 사용하고 있는지 확인하십시오.
프로비저닝 모드
AWS CLI를 사용하여 여러 DynamoDB 테이블의 용량 모드를 프로비저닝 모드로 변경하려면 다음 단계를 완료하십시오.
-
텍스트 편집기를 열고, 다음 코드를 입력하여 새 쉘 스크립트를 생성합니다.
#!/bin/bash # Set the AWS region AWS_REGION=[REGION] # Change this to your desired region # OPTION1: List of table names you want to switch TABLES=("table1" "table2" "table3") # OPTION2: Get all table names in the account TABLES=$(aws dynamodb list-tables —region $AWS_REGION —query 'TableNames[]' —output text) # Default provisioned capacity units READ_CAPACITY=READ_CAPACITY_VALUE WRITE_CAPACITY=WRITE_CAPACITY_VALUE echo "Using AWS Region: $AWS_REGION" for TABLE_NAME in $TABLES do # Check current billing mode CURRENT_MODE=$(aws dynamodb describe-table —region $AWS_REGION —table-name $TABLE_NAME —query 'Table.BillingModeSummary.BillingMode' —output text) if [ "$CURRENT_MODE" = "PAY_PER_REQUEST" ]; then echo "Processing table: $TABLE_NAME" # Get GSI configurations GSI_CONFIG="" GSI_LIST=$(aws dynamodb describe-table —region $AWS_REGION —table-name $TABLE_NAME —query 'Table.GlobalSecondaryIndexes[*].IndexName' —output text) if [ ! -z "$GSI_LIST" ]; then echo "Found GSIs: $GSI_LIST" # Build GSI provisioned throughput configuration GSI_CONFIG="—global-secondary-index-updates“ for GSI_NAME in $GSI_LIST do if [ -z "$FIRST_GSI" ]; then GSI_CONFIG="$GSI_CONFIG [{\"Update\":{\"IndexName\":\"$GSI_NAME\",\"ProvisionedThroughput\":{\"ReadCapacityUnits\":$READ_CAPACITY,\"WriteCapacityUnits\":$WRITE_CAPACITY}}}" FIRST_GSI="false" else GSI_CONFIG="$GSI_CONFIG,{\"Update\":{\"IndexName\":\"$GSI_NAME\",\"ProvisionedThroughput\":{\"ReadCapacityUnits\":$READ_CAPACITY,\"WriteCapacityUnits\":$WRITE_CAPACITY}}}" fi done GSI_CONFIG="$GSI_CONFIG]" fi # Update table and GSIs if [ ! -z "$GSI_CONFIG" ]; then echo "Updating table and GSIs..." aws dynamodb update-table \ --region $AWS_REGION \ --table-name $TABLE_NAME \ --billing-mode PROVISIONED \ --provisioned-throughput ReadCapacityUnits=$READ_CAPACITY,WriteCapacityUnits=$WRITE_CAPACITY \ $GSI_CONFIG else echo "Updating table (no GSIs)..." aws dynamodb update-table \ --region $AWS_REGION \ --table-name $TABLE_NAME \ --billing-mode PROVISIONED \ --provisioned-throughput ReadCapacityUnits=$READ_CAPACITY,WriteCapacityUnits=$WRITE_CAPACITY fi echo "Request submitted for $TABLE_NAME" else echo "Skipping $TABLE_NAME - already in PROVISIONED mode" fi # Reset GSI tracking for next table FIRST_GSI="" echo "----------------------------------------" done모든 DynamoDB 테이블의 용량 모드를 온디맨드 모드로 변경하려면 다음 코드 섹션을 삭제합니다.
#OPTION1: List of table names you want to switch TABLES=("table1" "table2" "table3")특정 DynamoDB 테이블의 용량 모드를 온디맨드 모드로 변경하려면 **"table1" "table2" "table3"**을 테이블 이름으로 바꾸십시오. 그런 다음 코드에서 다음 섹션을 제거합니다.
#OPTION2: Get all table names in the account TABLES=$(aws dynamodb list-tables —query 'TableNames[]' —output text)참고: READ_CAPACITY_VALUE와 WRITE_CAPACITY_VALUE를 읽기 및 쓰기 용량 값으로 바꾸십시오.
-
파일 이름을 switch-all-tables-with-gsi-to-provisioned.sh로 지정하고 저장합니다.
-
실행 가능한 파일을 만들려면 터미널을 열고 다음 명령을 실행합니다.
chmod +x switch-all-tables-with-gsi-to-provisioned.sh -
터미널에서 쉘 스크립트를 실행하려면 다음 명령을 실행합니다.
./switch-all-tables-with-gsi-to-provisioned.sh
온디맨드 모드
AWS CLI를 사용하여 여러 DynamoDB 테이블의 용량 모드를 온디맨드 모드로 변경하려면 다음 단계를 완료하십시오.
-
텍스트 편집기를 열고, 다음 코드를 입력하여 새 쉘 스크립트를 생성합니다.
#!/bin/bash # Set the AWS region AWS_REGION=[REGION] # Change this to your desired region # OPTION1: List of table names you want to switch TABLES=("table1" "table2" "table3") # OPTION2: Get all table names in the account #TABLES=$(aws dynamodb list-tables --region $AWS_REGION --query 'TableNames[]' --output text) for TABLE_NAME in $TABLES do # Check current billing mode CURRENT_MODE=$(aws dynamodb describe-table --region $AWS_REGION --table-name $TABLE_NAME --query 'Table.BillingModeSummary.BillingMode' --output text) if [ "$CURRENT_MODE" = "PROVISIONED" ]; then echo "Processing table: $TABLE_NAME" # Check if table has any GSIs GSI_LIST=$(aws dynamodb describe-table --region $AWS_REGION --table-name $TABLE_NAME --query 'Table.GlobalSecondaryIndexes[*].IndexName' --output text) if [ ! -z "$GSI_LIST" ]; then echo "Table has GSIs: $GSI_LIST" echo "Note: GSIs will automatically switch to On-Demand with the table" fi # Update table to On-Demand echo "Switching $TABLE_NAME to PAY_PER_REQUEST mode..." aws dynamodb update-table \ --region $AWS_REGION \ --table-name $TABLE_NAME \ --billing-mode PAY_PER_REQUEST echo "Request submitted for $TABLE_NAME" else echo "Skipping $TABLE_NAME - already in PAY_PER_REQUEST mode" fi echo "----------------------------------------" done모든 DynamoDB 테이블의 용량 모드를 온디맨드 모드로 변경하려면 다음 코드 섹션을 삭제합니다.
#OPTION1: List of table names you want to switch TABLES=("table1" "table2" "table3")특정 DynamoDB 테이블의 용량 모드를 온디맨드 모드로 변경하려면 **"table1" "table2" "table3"**을 테이블 이름으로 바꾸십시오. 그런 다음 코드에서 다음 섹션을 제거합니다.
`#OPTION2: Get all table names in the account` TABLES=$(aws dynamodb list-tables —region $AWS\_REGION —query 'TableNames\[\]' —output text)참고: REGION을 리전으로 바꾸십시오. 리전 코드(예: us-east-1)를 사용하십시오.
-
실행 가능한 파일을 만들려면 터미널을 열고 명령을 실행합니다.
chmod +x switch-all-tables-with-gsi-to-ondemand.sh -
터미널에서 쉘 스크립트를 실행하려면 명령을 실행합니다.
./switch-all-tables-with-gsi-to-ondemand.sh
CloudFormation
다음 모범 사례를 따르십시오.
- Python 3.9 런타임을 사용하도록 AWS Lambda 템플릿을 설정합니다.
- Amazon CloudWatch Logs를 모니터링하여 Lambda 함수의 진행 상황을 추적합니다.
참고: 시작 전에 AWS 자격 증명을 구성하십시오. configure AWS CLI 명령을 실행합니다.
aws configure
프로비저닝 모드
CloudFormation을 사용하여 여러 DynamoDB 테이블의 용량 모드를 프로비저닝 모드로 변경하려면 다음 단계를 완료하십시오.
-
텍스트 편집기를 열고, 다음 코드를 입력하여 새 YAML 파일을 생성합니다.
AWSTemplateFormatVersion: '2010-09-09' Description: 'Switch specific DynamoDB tables from On-Demand to Provisioned capacity mode' Parameters: ReadCapacityUnits: Type: Number Default: 5 Description: Read Capacity Units for tables and GSIs WriteCapacityUnits: Type: Number Default: 5 Description: Write Capacity Units for tables and GSIs TableNames: Type: CommaDelimitedList Description: Comma-separated list of DynamoDB table names to update Resources: DynamoDBTableUpdates: Type: Custom::DynamoDBTableUpdates Properties: ServiceToken: !GetAtt UpdateTablesFunction.Arn ReadCapacityUnits: !Ref ReadCapacityUnits WriteCapacityUnits: !Ref WriteCapacityUnits TableNames: !Ref TableNames UpdateTablesFunction: Type: AWS::Lambda::Function Properties: Runtime: python3.9 Handler: index.handler Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | import boto3 import cfnresponse def handler(event, context): try: if event['RequestType'] in ['Create', 'Update']: dynamodb = boto3.client('dynamodb') # Get parameters read_capacity = event['ResourceProperties']['ReadCapacityUnits'] write_capacity = event['ResourceProperties']['WriteCapacityUnits'] table_names = event['ResourceProperties']['TableNames'] for table_name in table_names: try: # Get table details table = dynamodb.describe_table(TableName=table_name)['Table'] current_mode = table.get('BillingModeSummary', {}).get('BillingMode', '') if current_mode == 'PAY_PER_REQUEST': # Prepare GSI updates if any gsi_updates = [] if 'GlobalSecondaryIndexes' in table: for gsi in table['GlobalSecondaryIndexes']: gsi_updates.append({ 'Update': { 'IndexName': gsi['IndexName'], 'ProvisionedThroughput': { 'ReadCapacityUnits': int(read_capacity), 'WriteCapacityUnits': int(write_capacity) } } }) # Update table update_params = { 'TableName': table_name, 'BillingMode': 'PROVISIONED', 'ProvisionedThroughput': { 'ReadCapacityUnits': int(read_capacity), 'WriteCapacityUnits': int(write_capacity) } } if gsi_updates: update_params['GlobalSecondaryIndexUpdates'] = gsi_updates dynamodb.update_table(**update_params) print(f"Switching {table_name} to PROVISIONED mode") else: print(f"Table {table_name} is not in PAY_PER_REQUEST mode. Skipping.") except Exception as e: print(f"Error processing table {table_name}: {str(e)}") continue cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) else: cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) except Exception as e: print(f"Error: {str(e)}") cfnresponse.send(event, context, cfnresponse.FAILED, {}) LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: DynamoDBAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:DescribeTable - dynamodb:UpdateTable Resource: '*' -
파일 이름을 switch-to-provisioned.yaml로 지정하고 저장합니다.
-
create-stack AWS CLI 명령을 실행합니다.
# For Provisioned mode aws cloudformation create-stack \ --stack-name switch-to-provisioned \ --template-body file://switch-to-provisioned.yaml \ --capabilities CAPABILITY_IAM \ --region [REGION] \ --parameters ParameterKey=TableNames,ParameterValue="Table1,Table2,Table3" \ ParameterKey=ReadCapacityUnits,ParameterValue=[RCU_VALUE] \ ParameterKey=WriteCapacityUnits,ParameterValue=[WCU_VALUE]참고: **"Table1,Table2,Table3"**을 테이블 이름으로, RCU_VALUE와 WCU_VALUE를 RCU 및 WCU 값으로, REGION을 리전(예: us-east-1)으로 바꾸십시오.
온디맨드 모드
CloudFormation을 사용하여 여러 DynamoDB 테이블의 용량 모드를 온디맨드 모드로 변경하려면 다음 단계를 완료하십시오.
-
텍스트 편집기를 열고, 다음 코드를 입력하여 새 YAML 파일을 생성합니다.
AWSTemplateFormatVersion: '2010-09-09' Description: 'Switch specific DynamoDB tables from Provisioned to On-Demand capacity mode' Parameters: TableNames: Type: CommaDelimitedList Description: Comma-separated list of DynamoDB table names to update Resources: DynamoDBTableUpdates: Type: Custom::DynamoDBTableUpdates Properties: ServiceToken: !GetAtt UpdateTablesFunction.Arn TableNames: !Ref TableNames UpdateTablesFunction: Type: AWS::Lambda::Function Properties: Runtime: python3.9 Handler: index.handler Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | import boto3 import cfnresponse def handler(event, context): try: if event['RequestType'] in ['Create', 'Update']: dynamodb = boto3.client('dynamodb') # Get table names from the event table_names = event['ResourceProperties']['TableNames'] for table_name in table_names: try: # Get table details table = dynamodb.describe_table(TableName=table_name)['Table'] current_mode = table.get('BillingModeSummary', {}).get('BillingMode', '') if current_mode == 'PROVISIONED': # Update table to On-Demand dynamodb.update_table( TableName=table_name, BillingMode='PAY_PER_REQUEST' ) print(f"Switching {table_name} to PAY_PER_REQUEST mode") else: print(f"Table {table_name} is not in PROVISIONED mode. Skipping.") except Exception as e: print(f"Error processing table {table_name}: {str(e)}") continue cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) else: cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) except Exception as e: print(f"Error: {str(e)}") cfnresponse.send(event, context, cfnresponse.FAILED, {}) LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: DynamoDBAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:DescribeTable - dynamodb:UpdateTable Resource: '*' -
파일 이름을 switch-to-ondemand.yaml로 지정하고 저장합니다.
-
create-stack AWS CLI 명령을 실행합니다.
# For On-Demand mode aws cloudformation create-stack \ --stack-name switch-to-ondemand \ --template-body file://switch-to-ondemand.yaml \ --capabilities CAPABILITY_IAM \ --region [REGION] \ --parameters ParameterKey=TableNames,ParameterValue="Table1,Table2,Table3"참고: **"Table1,Table2,Table3"**을 테이블 이름으로, REGION을 리전으로 바꾸십시오.
Python
Amazon Elastic Compute Cloud(EC2) 인스턴스, Lambda 또는 자체 데스크톱을 사용하여 Python 스크립트를 실행할 수 있습니다. 용량 모드를 변경하기 전에 Python, pip, boto3를 설치했는지 확인하십시오.
시작 전에 AWS 자격 증명을 구성하십시오. configure AWS CLI 명령을 실행합니다.
aws configure
프로비저닝 모드
Python 스크립트를 사용하여 특정 리전에 있는 모든 DynamoDB 테이블의 용량 모드를 프로비저닝 모드로 변경하려면 다음 단계를 완료하십시오.
-
Python을 열고, 다음 코드를 입력하여 새 파일을 생성합니다.
import boto3 import time from botocore.exceptions import ClientError def switch_to_provisioned(read_capacity=5, write_capacity=5, region=None): """ Switch all DynamoDB tables from On-Demand to Provisioned capacity mode """ # Initialize DynamoDB client dynamodb = boto3.client('dynamodb', region_name=region) # Get all table names tables = [] paginator = dynamodb.get_paginator('list_tables') for page in paginator.paginate(): tables.extend(page['TableNames']) print(f"Found {len(tables)} tables") for table_name in tables: try: # Get table details response = dynamodb.describe_table(TableName=table_name) table = response['Table'] current_mode = table.get('BillingModeSummary', {}).get('BillingMode', '') if current_mode == 'PAY_PER_REQUEST': print(f"\nProcessing table: {table_name}") # Prepare GSI updates if any gsi_updates = [] if 'GlobalSecondaryIndexes' in table: print(f"Found GSIs for table {table_name}") for gsi in table['GlobalSecondaryIndexes']: gsi_updates.append({ 'Update': { 'IndexName': gsi['IndexName'], 'ProvisionedThroughput': { 'ReadCapacityUnits': read_capacity, 'WriteCapacityUnits': write_capacity } } }) # Prepare update parameters update_params = { 'TableName': table_name, 'BillingMode': 'PROVISIONED', 'ProvisionedThroughput': { 'ReadCapacityUnits': read_capacity, 'WriteCapacityUnits': write_capacity } } if gsi_updates: update_params['GlobalSecondaryIndexUpdates'] = gsi_updates # Update table print(f"Switching {table_name} to PROVISIONED mode...") dynamodb.update_table(**update_params) print(f"Update request submitted for {table_name}") else: print(f"\nSkipping {table_name} - already in PROVISIONED mode") except ClientError as e: if e.response['Error']['Code'] == 'LimitExceededException': print(f"\nError: Cannot update {table_name}. You can only switch between billing modes once per 24 hours.") else: print(f"\nError processing table {table_name}: {str(e)}") continue except Exception as e: print(f"\nUnexpected error processing table {table_name}: {str(e)}") continue # Small delay to avoid API throttling time.sleep(1) if __name__ == "__main__": # You can modify these values READ_CAPACITY = [RCU_VALUE] WRITE_CAPACITY = [WCU_VALUE] REGION = [REGION] # Change to your desired region switch_to_provisioned( read_capacity=READ_CAPACITY, write_capacity=WRITE_CAPACITY, region=REGION )참고: RCU_VALUE와 WCU_VALUE를 RCU 및 WCU 값으로, REGION을 리전(예: us-east-1)으로 바꾸십시오.
-
파일 이름을 switch_to_provisioned.py로 지정하고 저장합니다.
-
터미널을 열고 다음 명령을 실행하여 Python 스크립트를 실행합니다.
python switch_to_provisioned.py
온디맨드 모드
Python 스크립트를 사용하여 특정 리전에 있는 모든 DynamoDB 테이블의 용량 모드를 온디맨드 모드로 변경하려면 다음 단계를 완료하십시오.
-
Python을 열고, 다음 코드를 입력하여 새 파일을 생성합니다.
import boto3 import time from botocore.exceptions import ClientError def switch_to_ondemand(region=None): """ Switch all DynamoDB tables from Provisioned to On-Demand capacity mode """ # Initialize DynamoDB client dynamodb = boto3.client('dynamodb', region_name=region) # Get all table names tables = [] paginator = dynamodb.get_paginator('list_tables') for page in paginator.paginate(): tables.extend(page['TableNames']) print(f"Found {len(tables)} tables") for table_name in tables: try: # Get table details response = dynamodb.describe_table(TableName=table_name) table = response['Table'] current_mode = table.get('BillingModeSummary', {}).get('BillingMode', '') if current_mode == 'PROVISIONED': print(f"\nProcessing table: {table_name}") # Check for GSIs if 'GlobalSecondaryIndexes' in table: print(f"Table {table_name} has GSIs - they will automatically switch to On-Demand") # Update table print(f"Switching {table_name} to PAY_PER_REQUEST mode...") dynamodb.update_table( TableName=table_name, BillingMode='PAY_PER_REQUEST' ) print(f"Update request submitted for {table_name}") else: print(f"\nSkipping {table_name} - already in PAY_PER_REQUEST mode") except ClientError as e: if e.response['Error']['Code'] == 'LimitExceededException': print(f"\nError: Cannot update {table_name}. You can only switch between billing modes once per 24 hours.") else: print(f"\nError processing table {table_name}: {str(e)}") continue except Exception as e: print(f"\nUnexpected error processing table {table_name}: {str(e)}") continue # Small delay to avoid API throttling time.sleep(1) def check_table_status(table_name, region=None): """ Check the current billing mode of a specific table """ dynamodb = boto3.client('dynamodb', region_name=region) try: response = dynamodb.describe_table(TableName=table_name) mode = response['Table'].get('BillingModeSummary', {}).get('BillingMode', 'Unknown') print(f"Table {table_name} is in {mode} mode") return mode except Exception as e: print(f"Error checking table {table_name}: {str(e)}") return None if __name__ == "__main__": REGION = [REGION] # Change to your desired region switch_to_ondemand(region=REGION)참고: REGION을 리전으로 바꾸십시오.
-
파일 이름을 switch_to_ondemand.py로 지정하고 저장합니다.
-
터미널을 열고 다음 명령을 실행하여 Python 스크립트를 실행합니다.
python switch_to_ondemand.py
관련 정보
관련 콘텐츠
- 질문됨 일 년 전
AWS 공식업데이트됨 한 달 전