Boto S3偶尔会抛出httplib.IncompleteRead

问题描述 投票:9回答:3

我有几个守护程序,可以使用boto从Amazon S3读取许多文件。每两天一次,我遇到了一个情况,即从内部boto中抛出了一个httplib.IncompleteRead。如果我尝试重试该请求,它将立即失败,并显示另一个IncompleteRead。即使我呼叫bucket.connection.close(),所有其他请求仍然会出错。

我觉得我可能在这里偶然发现了boto中的一个错误,但似乎没有其他人遇到它。难道我做错了什么?所有的守护程序都是单线程的,我尝试了两种方式都设置is_secure

Traceback (most recent call last):
  ...
  File "<file_wrapper.py",> line 22, in next
    line = self.readline()
  File "<file_wrapper.py",> line 37, in readline
    data = self.fh.read(self.buffer_size)
  File "<virtualenv/lib/python2.6/site-packages/boto/s3/key.py",> line 378, in read
    self.close()
  File "<virtualenv/lib/python2.6/site-packages/boto/s3/key.py",> line 349, in close
    self.resp.read()
  File "<virtualenv/lib/python2.6/site-packages/boto/connection.py",> line 411, in read
    self._cached_response = httplib.HTTPResponse.read(self)
  File "/usr/lib/python2.6/httplib.py", line 529, in read
    s = self._safe_read(self.length)
  File "/usr/lib/python2.6/httplib.py", line 621, in _safe_read
    raise IncompleteRead(''.join(s), amt)

环境:

  • Amazon EC2
  • Ubuntu 11.10
  • Python 2.6.7
  • Boto 2.12.0
python amazon-s3 boto
3个回答
4
投票

这很可能是boto中的错误,但是您描述的症状并非唯一。参见

IncompleteRead using httplib

https://dev.twitter.com/discussions/9554

由于httplib出现在您的追溯中,因此在这里提出了一种解决方案:

http://bobrochel.blogspot.in/2010/11/bad-servers-chunked-encoding-and.html?showComment=1358777800048

免责声明:我没有boto的经验。这仅基于研究,并且由于没有其他回应而发布。


3
投票

我一直在为此问题苦苦挣扎,正在运行长时间运行的进程,这些进程从S3中读取大量数据。我决定将解决方案发布在这里,以供后代使用。

首先,我确定@Glenn所指的黑客是可行的,但我选择不使用它,因为我认为它具有侵入性(攻击httplib)且不安全(它盲目返回所得到的信息,即return e.partial,尽管事实可能是真实错误的情况。

这是我最后想出的解决方案,似乎很奏效。

我正在使用此通用重试功能:

import time, logging, httplib, socket

def run_with_retries(func, num_retries, sleep = None, exception_types = Exception, on_retry = None):
    for i in range(num_retries):
        try:
            return func()  # call the function
        except exception_types, e:
            # failed on the known exception
            if i == num_retries - 1:
                raise  # this was the last attempt. reraise
            logging.warning(f'operation {func} failed with error {e}. will retry {num_retries-i-1} more times')
            if on_retry is not None:
                on_retry()
            if sleep is not None:
                time.sleep(sleep)
    assert 0  # should not reach this point

[现在,当从S3读取文件时,我正在使用此功能,在发生IncompleteRead错误的情况下,该功能在内部执行重试。发生错误时,在重试之前,我会呼叫key.close()

def read_s3_file(key):
    """
    Reads the entire contents of a file on S3.
    @param key: a boto.s3.key.Key instance
    """
    return run_with_retries(
        key.read, num_retries = 3, sleep = 0.5,
        exception_types = (httplib.IncompleteRead, socket.error),
        # close the connection before retrying
        on_retry = lambda: key.close()
    )

0
投票

如果要从S3读取大量数据,则可能必须对读/写进行大块/多部分处理。

这里有一个很好的例子,可以做多部分(http://www.bogotobogo.com/DevOps/AWS/aws_S3_uploading_large_file.php

© www.soinside.com 2019 - 2024. All rights reserved.