繁体   English   中英

使用 Python boto3 从 AWS S3 存储桶读取文本文件和超时错误

[英]Reading text files from AWS S3 bucket using Python boto3 and timeout error

我想使用 boto3 package 从 AWS S3 存储桶中读取大量文本文件。 由于文本文件的数量太大,我还使用了来自 joblib 的分页器和并行 function。 这是我用来读取 S3 存储桶 (S3_bucket_name) 中文件的代码:

import boto3
from joblib import Parallel, delayed

# ignore warnings
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

#
s3_client = boto3.client('s3', # verify=False,
                        aws_access_key_id = my_aws_access_key, 
                        aws_secret_access_key = my_aws_secret,
                        region_name = aws_region_name)
# 
resource = boto3.resource(
    's3', #verify=False,
    aws_access_key_id = my_aws_access_key, 
    aws_secret_access_key = my_aws_secret,
    region_name = aws_region_name)
)


# The Paginator
paginator = s3_client.get_paginator('list_objects')
operation_parameters = {'Bucket': S3_bucket_name}
page_iterator = paginator.paginate(**operation_parameters)

def read_s3_txt(Bucket, filename):
    return str(resource.Object(Bucket, filename).get()['Body'].read(),"utf-8")

# Read page by page and add them in text_contents
text_contents = []
for page in page_iterator:
    files = page.get("Contents")    
    # read files in parallel   
    texts = Parallel(n_jobs=-1, prefer="threads")(delayed(read_s3_txt)(S3_bucket_name, file['Key']) for file in files) 
    text_contents.extend(texts)

上面的代码运行良好,但是我在第 2 页的 read.txt 文件中遇到了“无”URL 的错误。对于此类错误,我找不到任何 stackoverflow 或 github 页面。 对于某些 of.txt 文件,看起来端点 URL 是“无”的。 我的问题是 1)如果错误与那些“无”端点相关,我如何排除阅读那些“无”URL 以及 2)如何优化代码并使其快速读取数百万条记录,因为目前读取需要 25 分钟100,000.txt 文件,32GB RAM。

非常感谢您的帮助!

*错误:

timeout                                   Traceback (most recent call last)
~\AppData\Roaming\Python\Python39\site-packages\urllib3\response.py in _error_catcher(self)
440             try:
--> 441                 yield
442 

~\AppData\Roaming\Python\Python39\site-packages\urllib3\response.py in read(self, amt, decode_content, cache_content)
517                 # cStringIO doesn't like amt=None
--> 518                 data = self._fp.read() if not fp_closed else b""
519                 flush_decoder = True

c:\Program Files\Python39\lib\http\client.py in read(self, amt)
467                 try:
--> 468                     s = self._safe_read(self.length)
469                 except IncompleteRead:

c:\Program Files\Python39\lib\http\client.py in _safe_read(self, amt)
608         """
--> 609         data = self.fp.read(amt)
610         if len(data) < amt:

c:\Program Files\Python39\lib\socket.py in readinto(self, b)
703             try:
--> 704                 return self._sock.recv_into(b)
...
--> 102             raise ReadTimeoutError(endpoint_url=e.url, error=e)
103         except URLLib3ProtocolError as e:
104             raise ResponseStreamingError(error=e)

ReadTimeoutError: Read timeout on endpoint URL: "None"

我为我的情况找到了一个可行的解决方案。 可能是其他一些原因,但以下更改对我有用。 看起来该错误与“无”url 端点无关,更多的是关于配置文件中的 max_attempts。

  1. 我用“list_objects_v2”替换了“list_objects”,有趣的是,错误消失了。 此更改也有助于提高速度,并将速度提高了大约 1.5。

    paginator = s3_client.get_paginator('list_objects')

  2. 我发现它有用的另一件事是为“超时错误”添加以下内容。

    从 botocore.client 导入配置
    配置=配置(重试= {'max_attempts':10,'模式':'标准'})

max_attempts 的默认值为 5。

欢迎其他评论/答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM