并发删除多S3桶内容的Python及Bash脚本报错求助
问题解决指南
一、Python脚本 KeyError: 'endpoint_resolver' 错误修复
这个错误是由于boto3客户端实例线程不安全引发的随机问题,加上旧版本依赖的潜在bug导致。
解决方案
升级依赖包
先确保boto3和botocore是最新版本:pip install --upgrade boto3 botocore修改脚本:每个并发任务单独创建S3客户端
不要在多线程间共享boto3客户端实例,每个线程内单独初始化客户端。以下是优化后的脚本,支持超1000对象批量删除、并发处理6个桶:import boto3 from concurrent.futures import ThreadPoolExecutor, as_completed def empty_bucket(bucket_name): # 每个任务单独创建S3客户端 s3 = boto3.client('s3') paginator = s3.get_paginator('list_objects_v2') delete_batch = [] # 分页遍历所有对象 for page in paginator.paginate(Bucket=bucket_name): if 'Contents' in page: delete_batch.extend([{'Key': obj['Key']} for obj in page['Contents']]) # 批量删除(每次最多1000个对象) while len(delete_batch) >= 1000: batch = delete_batch[:1000] s3.delete_objects(Bucket=bucket_name, Delete={'Objects': batch}) delete_batch = delete_batch[1000:] # 删除剩余不足1000的对象 if delete_batch: s3.delete_objects(Bucket=bucket_name, Delete={'Objects': delete_batch}) if __name__ == '__main__': target_buckets = ["bucket1", "bucket2", "bucket3", "bucket4", "bucket5", "bucket6"] # 并发数设为6,和桶数量一致 with ThreadPoolExecutor(max_workers=6) as executor: futures = [executor.submit(empty_bucket, bucket) for bucket in target_buckets] # 等待所有任务完成并捕获异常 for future in as_completed(futures): try: future.result() print(f"桶内容清空完成") except Exception as e: print(f"清空桶失败: {str(e)}")
二、Bash脚本 jq 错误修复
Cannot index array with string "Key" 错误是因为当桶内无对象时,aws s3api list-objects-v2 返回结果中没有Contents字段,jq直接索引会报错。同时单对象删除速度慢,改用批量删除优化。
解决方案
修改脚本逻辑,先判断Contents是否存在,同时用批量删除提升效率:
#!/bin/bash BUCKETS=("bucket1" "bucket2" "bucket3" "bucket4" "bucket5" "bucket6") empty_bucket() { local BUCKET=$1 # 分页获取所有对象Key,处理空桶场景 aws s3api list-objects-v2 --bucket "$BUCKET" --output json | jq -c ' if .Contents then .Contents[] | {Key: .Key} else empty end ' > "/tmp/${BUCKET}_keys.tmp" # 按1000个一组批量删除 jq -s -c '.[] | _nwise(1000)' "/tmp/${BUCKET}_keys.tmp" | while read -r BATCH; do aws s3api delete-objects --bucket "$BUCKET" --delete "{\"Objects\": $BATCH}" done # 若桶开启版本化,需额外删除版本和删除标记(可选) aws s3api list-object-versions --bucket "$BUCKET" --output json | jq -c ' (.Versions[]? | {Key: .Key, VersionId: .VersionId}), (.DeleteMarkers[]? | {Key: .Key, VersionId: .VersionId}) ' > "/tmp/${BUCKET}_versions.tmp" jq -s -c '.[] | _nwise(1000)' "/tmp/${BUCKET}_versions.tmp" | while read -r BATCH; do aws s3api delete-objects --bucket "$BUCKET" --delete "{\"Objects\": $BATCH}" done rm "/tmp/${BUCKET}_keys.tmp" "/tmp/${BUCKET}_versions.tmp" } # 并发执行所有桶的清空任务 for BUCKET in "${BUCKETS[@]}"; do empty_bucket "$BUCKET" & done wait
三、aws s3 rm 提速方案
如果坚持用官方CLI,可添加--parallel参数开启并发删除:
aws s3 rm s3://your-bucket --recursive --parallel
但批量删除的效率仍远高于此命令。
内容的提问来源于stack exchange,提问作者gamechanger17
相关产品推荐
相关产品推荐

