wol*_*lak 9 python amazon-s3 boto
我有几个守护进程使用boto从Amazon S3读取许多文件.每隔几天,我就遇到了一个从深入的boto中抛出httplib.IncompleteRead的情况.如果我尝试重试请求,它会立即失败并使用另一个IncompleteRead.即使我打电话bucket.connection.close(),所有进一步的请求仍然会出错.
我觉得我可能偶然发现了这里的boto中的一个bug,但似乎没有其他人能够击中它.难道我做错了什么?所有的守护进程都是单线程的,我试过设置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)
Run Code Online (Sandbox Code Playgroud)
环境:
我已经为这个问题苦苦挣扎了一段时间,运行长时间运行的进程,从 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
Run Code Online (Sandbox Code Playgroud)
现在,当从 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()
)
Run Code Online (Sandbox Code Playgroud)
小智 4
这很可能是 boto 中的一个错误,但您描述的症状并不是它独有的。看
https://dev.twitter.com/discussions/9554
由于 httplib 出现在您的回溯中,因此这里提出了一种解决方案:
http://bobrochel.blogspot.in/2010/11/bad-servers-chunked-encoding-and.html?showComment=1358777800048
免责声明:我没有 boto 的经验。这仅基于研究并发布,因为没有其他回应。
| 归档时间: |
|
| 查看次数: |
2369 次 |
| 最近记录: |