使用Boto3为DynamoDB配置自动扩缩容策略时遇ObjectNotFoundException
解决DynamoDB自动扩缩容策略的ObjectNotFoundException错误
嘿,我来帮你搞定这个问题!你碰到的ObjectNotFoundException其实是个很常见的坑——AWS Auto Scaling要求必须先把DynamoDB表或者索引注册成可扩缩目标,之后才能给它绑定扩缩容策略。你之前的代码跳过了注册这一步,所以服务找不到对应的资源,就报错了。
核心解决方案:先注册可扩缩目标
在调用PutScalingPolicy之前,你需要用application-autoscaling客户端的register_scalable_target方法,把DynamoDB资源(表/索引)注册到Auto Scaling服务中。下面是完整的修正代码示例:
import boto3 def register_scalable_target(resource_type, resource_name, index_name=None, min_cap=1, max_cap=10): """注册DynamoDB表或索引为可扩缩目标""" asg_client = boto3.client('application-autoscaling') # 根据资源类型构建正确的ResourceID和维度 if resource_type == 'table': resource_id = f'table/{resource_name}' scalable_dimension = 'dynamodb:table:ReadCapacityUnits' elif resource_type == 'index': if not index_name: raise ValueError("索引名称不能为空哦!") resource_id = f'table/{resource_name}/index/{index_name}' scalable_dimension = 'dynamodb:index:ReadCapacityUnits' else: raise ValueError("资源类型只能是'table'或'index'") # 执行注册操作 return asg_client.register_scalable_target( ServiceNamespace='dynamodb', ResourceId=resource_id, ScalableDimension=scalable_dimension, MinCapacity=min_cap, MaxCapacity=max_cap ) def set_scaling_policy(resource_type, resource_name, index_name=None, policy_name='DynamoDBReadScalingPolicy'): """设置DynamoDB资源的自动扩缩容策略""" asg_client = boto3.client('application-autoscaling') # 先确保资源已注册(如果未注册则自动注册) register_scalable_target(resource_type, resource_name, index_name) # 再次构建资源标识(和注册时保持一致) if resource_type == 'table': resource_id = f'table/{resource_name}' scalable_dimension = 'dynamodb:table:ReadCapacityUnits' else: resource_id = f'table/{resource_name}/index/{index_name}' scalable_dimension = 'dynamodb:index:ReadCapacityUnits' # 绑定扩缩容策略(这里用目标追踪策略,你可以根据需求调整) return asg_client.put_scaling_policy( PolicyName=policy_name, ServiceNamespace='dynamodb', ResourceId=resource_id, ScalableDimension=scalable_dimension, PolicyType='TargetTrackingScaling', TargetTrackingScalingPolicyConfiguration={ 'TargetValue': 70.0, # 目标利用率设为70% 'PredefinedMetricSpecification': { 'PredefinedMetricType': 'DynamoDBReadCapacityUtilization' }, 'ScaleOutCooldown': 60, # 扩容冷却60秒 'ScaleInCooldown': 300 # 缩容冷却300秒 } ) # 使用示例:给表设置读容量扩缩容 set_scaling_policy('table', 'your-table-name') # 使用示例:给全局二级索引设置读容量扩缩容 # set_scaling_policy('index', 'your-table-name', 'your-index-name')
常见避坑点
资源ID格式必须准确
- 表的格式:
table/TableName - 全局二级索引的格式:
table/TableName/index/IndexName
格式错一点都会导致找不到资源。
- 表的格式:
权限要到位
你的Lambda执行角色需要包含以下IAM权限,否则会出现权限错误:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "application-autoscaling:RegisterScalableTarget", "application-autoscaling:PutScalingPolicy", "application-autoscaling:DescribeScalableTargets" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "dynamodb:DescribeTable", "dynamodb:UpdateTable" ], "Resource": "arn:aws:dynamodb:*:*:table/*" } ] }避免重复注册
如果担心重复调用register_scalable_target,可以先调用describe_scalable_targets检查目标是否已注册,再决定是否执行注册操作。
内容的提问来源于stack exchange,提问作者Patrick N
相关产品推荐
相关产品推荐

