某些第三方应用程序一天内将大约 10000 个对象上传到我的存储桶+前缀。我的要求是获取过去 24 小时内上传到我的存储桶+前缀的所有对象。
我的bucket+前缀里有这么多文件。
所以我假设当我打电话时
response = s3_paginator.paginate(Bucket=bucket,Prefix='inside-bucket-level-1/', PaginationConfig={"PageSize": 1000})
那么它可能会多次调用 S3 API,这可能就是它显示 Rate Exceeded 错误的原因。
下面是我的 Python Lambda 函数。
import json
import boto3
import time
from datetime import datetime, timedelta
def lambda_handler(event, context):
s3 = boto3.client("s3")
from_date = datetime.today() - timedelta(days=1)
string_from_date = from_date.strftime("%Y-%m-%d, %H:%M:%S")
print("Date :", string_from_date)
s3_paginator = s3.get_paginator('list_objects_v2')
list_of_buckets = ['kush-dragon-data']
bucket_wise_list = {}
for bucket in list_of_buckets:
response = s3_paginator.paginate(Bucket=bucket,Prefix='inside-bucket-level-1/', PaginationConfig={"PageSize": 1000})
filtered_iterator = response.search(
"Contents[?to_string(LastModified)>='\"" + string_from_date + "\"'].Key")
keylist = []
for key_data in filtered_iterator:
if "/" in key_data:
splitted_array = key_data.split("/")
if len(splitted_array) > 1:
if splitted_array[-1]:
keylist.append(splitted_array[-1])
else:
keylist.append(key_data)
bucket_wise_list.update({bucket: keylist})
print("Total Number Of Object = ", bucket_wise_list)
# TODO implement
return {
'statusCode': 200,
'body': json.dumps(bucket_wise_list)
}
因此,当我们执行上面的 Lambda 函数时,它会显示以下错误。
“调用调用 API 操作失败,并显示以下消息:速率超出。”
任何人都可以帮助解决此错误并实现我的要求吗?
这可能是由于您的帐户限制,您应该在重试之间添加几秒钟的重试或增加页面大小
这很可能是由于您达到了 AWS S3 API 调用的配额限制。 “更大的锤子”解决方案是请求增加配额,但如果您不想这样做,还有另一种方法使用
botocore.Config
内置重试,例如:
import json
import time
from datetime import datetime, timedelta
from boto3 import client
from botocore.config import Config
config = Config(
retries = {
'max_attempts': 10,
'mode': 'standard'
}
)
def lambda_handler(event, context):
s3 = client('s3', config=config)
###ALL OF YOUR CURRENT PYTHON CODE EXACTLY THE WAY IT IS###
此配置将使用指数增加的睡眠计时器来实现最大重试次数。来自文档:
还有一种
adaptive
模式仍处于实验阶段。有关更多信息,请参阅有关 botocore.Config
重试的docs
另一个(在我看来不太健壮的)选择是编写自己的分页器,并在其中编程睡眠,尽管您可能只想在 99.99% 的情况下使用内置的退避功能(即使您确实必须编写自己的分页器)。 (此代码未经测试,甚至不是异步的,因此睡眠将不包括在页面响应的等待时间之外。要使“睡眠时间”精确到
sleep_secs
,您需要使用 concurrent.futures
或asyncio
(AWS内置分页器主要使用concurrent.futures
)):
from boto3 import client
from typing import Generator
from time import sleep
def get_pages(bucket:str,prefix:str,page_size:int,sleep_secs:float) -> Generator:
s3 = client('s3')
page:dict = client.list_objects_v2(
Bucket=bucket,
MaxKeys=page_size,
Prefix=prefix
)
next_token:str = page.get('NextContinuationToken')
yield page
while(next_token):
sleep(sleep_secs)
page = client.list_objects_v2(
Bucket=bucket,
MaxKeys=page_size,
Prefix=prefix,
ContinuationToken=next_token
)
next_token = page.get('NextContinuationToken')
yield page