【问题标题】:Seeing hangs (no timeout) on aiobotocore response['Body'].read(...)在 aiobotocore 响应 ['Body'].read(...) 上看到挂起(没有超时)
【发布时间】:2019-09-20 14:58:00
【问题描述】:

我正在使用 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 中获取异常?

【问题讨论】:

    标签: boto3 python-asyncio botocore


    【解决方案1】:

    这里的问题是超时是每个协程的,你不应该在单个协程中多次迭代读取,而应该将多个协程提交给事件线程以运行read 多次。在大文件的情况下,您也无法一次读取整个文件。对我来说效果很好的方法是向偶数循环提交单独的协程,每个协程从 Body iostream 中读取 1MB 块。这样,您就不会得到在 1 个协程内超时的大文件,也不会得到大量协程,这些协程最终会产生开销并在事件循环上消耗太多时间(即 1 个线程,1 个核心最大),8k 太小了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-10
      • 2015-06-02
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 1970-01-01
      • 2016-08-06
      • 1970-01-01
      相关资源
      最近更新 更多