我正在尝试将大量文件上传到 S3。由于磁盘上的文件名和 S3 中的对象名称之间需要转换,因此无法使用标准 AWS CLI 来完成此操作。 事实上,磁盘上可能根本不存在这些对象。
我不断收到错误:
botocore.exceptions.ClientError: An error occurred (SlowDown) when calling the PutObject operation (reached max retries: 0): Please reduce your request rate
我是否使用 boto3 / botocore / aioboto3 / aiobotocore 似乎没有什么区别。 我已经尝试了各种重试逻辑配置,如here所述。 似乎没有什么可以解决这个问题。 这包括所有三种重试模式和从 0 到 50 的重试计数。
我可以向调用客户端的每个方法添加自定义重试逻辑,但这将需要大量工作,而且感觉是错误的方法。
是否可以自定义boto3或aiobotocore使用的重试逻辑?
使用AioConfig,Config的异步扩展。就像使用标准 boto3 一样将其传递给客户端。
下面的代码最终将检索包含 20 个组织根响应副本的列表。它打印获得每个响应所需的重试次数的列表。
ListRoots是一个方便的测试功能,因为它只读取数据,并且具有较低的节流限制(每个帐户,每秒 1 个和 2 个突发)。
import asyncio
from aioboto3 import Session
from aiobotocore.config import AioConfig
try_hard = AioConfig(retries={"max_attempts": 100})
async def main():
coro = Session().client("organizations", config=try_hard)
async with coro as client:
resp_list = await asyncio.gather(
*[client.list_roots() for _ in range(20)]
)
print([r["ResponseMetadata"]["RetryAttempts"] for r in resp_list])
asyncio.run(main())
它将返回一个包含如下对象的列表:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 6, 4, 4, 4, 4, 4, 5, 5]
列表按响应时间戳排序,最早的在前。前 10 个响应不会重试。接下来的 10 个响应均需要重试 4 到 6 次。
默认的
max_retries
值为 4。这对于 20 个并发请求来说是不够的。如果删除 config
参数,代码肯定会像这样失败。
botocore.errorfactory.TooManyRequestsException: An error occurred (TooManyRequestsException) when calling the ListRoots operation (reached max retries: 4): AWS Organizations can't complete your request because another request is already in progress. Try again later.