在 aiobotocore 响应 ['Body'].read(...) 上看到挂起(无超时)
Seeing hangs (no timeout) on aiobotocore response['Body'].read(...)
使用 aiobotocore 创建客户端使用:
import botocore
import aiobotocore
s3_session = aiobotocore.get_session(loop=loop)
client = s3_session.create_client(
's3',
config=botocore.client.Config(connect_timeout=10, read_timeout=10, retries={'max_attempts': 0}),
endpoint_url=endpoint_url,
)
稍后我得到了一个以 8k 块读取的异步函数:
async def aio_read(bucket, key, range_header):
s3_object = await self.client.get_object(Bucket=bucket, Key=key, Range=range_header)
s3_iostream = s3_object['Body']
b = None
body_data = b''
while b != b'':
b = await s3_iostream.read(8192)
body_data += b
print('{}> len(b) / len(body_data) = {}/{}'.format(uuid, len(b), len(body_data)))
我正在测试的下载大小为 1MB,以 8k 块读取。当我 运行 100 个并行进程时,我通常会挂起一些进程,并且通过上面的 print
语句,我可以看到其中一个 aio_read
函数在读取文件的过程中停止了.
正文读取操作似乎超时,然后无限期挂起。
如果发生读取超时,是否有办法从 aiobotocore 中获取异常?
这里的问题是超时是每个协程的,你不应该在一个协程中多次迭代读取,而你应该将多个协程提交给事件线程 运行 read
多次。对于大文件,您也无法一次读取整个文件。对我来说效果很好的方法是将单独的协程提交给偶数循环,每个协程从 Body iostream 读取 1MB 的块。这样你就不会得到在 1 个协程内超时的大文件,也不会得到大量的协程,这些协程最终会产生开销并在事件循环(1 个线程,1 个核心)上消耗太多时间最大值),8k 太小了。
使用 aiobotocore 创建客户端使用:
import botocore
import aiobotocore
s3_session = aiobotocore.get_session(loop=loop)
client = s3_session.create_client(
's3',
config=botocore.client.Config(connect_timeout=10, read_timeout=10, retries={'max_attempts': 0}),
endpoint_url=endpoint_url,
)
稍后我得到了一个以 8k 块读取的异步函数:
async def aio_read(bucket, key, range_header):
s3_object = await self.client.get_object(Bucket=bucket, Key=key, Range=range_header)
s3_iostream = s3_object['Body']
b = None
body_data = b''
while b != b'':
b = await s3_iostream.read(8192)
body_data += b
print('{}> len(b) / len(body_data) = {}/{}'.format(uuid, len(b), len(body_data)))
我正在测试的下载大小为 1MB,以 8k 块读取。当我 运行 100 个并行进程时,我通常会挂起一些进程,并且通过上面的 print
语句,我可以看到其中一个 aio_read
函数在读取文件的过程中停止了.
正文读取操作似乎超时,然后无限期挂起。
如果发生读取超时,是否有办法从 aiobotocore 中获取异常?
这里的问题是超时是每个协程的,你不应该在一个协程中多次迭代读取,而你应该将多个协程提交给事件线程 运行 read
多次。对于大文件,您也无法一次读取整个文件。对我来说效果很好的方法是将单独的协程提交给偶数循环,每个协程从 Body iostream 读取 1MB 的块。这样你就不会得到在 1 个协程内超时的大文件,也不会得到大量的协程,这些协程最终会产生开销并在事件循环(1 个线程,1 个核心)上消耗太多时间最大值),8k 太小了。