2013-10-15 18 views
8

Tôi có một vài trình tiện ích đọc nhiều tệp từ Amazon S3 bằng boto. Vài ngày một lần, tôi chạy vào một tình huống mà một httplib.IncompleteRead được ném ra từ sâu bên trong boto. Nếu tôi thử và thử lại yêu cầu, nó sẽ ngay lập tức thất bại với một IncompleteRead khác. Ngay cả khi tôi gọi bucket.connection.close(), tất cả các yêu cầu khác sẽ vẫn bị lỗi.Boto S3 ném httplib.IncompleteRead thỉnh thoảng

Tôi cảm thấy như tôi có thể đã tình cờ gặp một lỗi trong boto ở đây, nhưng không ai khác có vẻ đã đánh nó. Tôi có làm điều gì sai? Tất cả các daemon đều đơn luồng và tôi đã thử đặt cả hai cách.

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) 

Môi trường:

  • Amazon EC2
  • Ubuntu 11.10
  • Python 2.6.7
  • Boto 2.12.0

Trả lời

2

Nó cũng có thể là một lỗi trong boto , nhưng các triệu chứng bạn mô tả không phải là duy nhất cho nó. Xem

IncompleteRead using httplib

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

Kể từ khi xuất hiện trong httplib traceback của bạn, một trong những giải pháp được đề xuất ở đây:

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

Disclaimer: Tôi không có kinh nghiệm với boto. Điều này chỉ dựa trên nghiên cứu và được đăng vì không có phản hồi nào khác.

+0

Cảm ơn bạn đã nỗ lực. Tôi vẫn chưa tìm thấy một giải pháp tốt cho điều này, nhưng bạn xứng đáng được thưởng hơn bất cứ ai khác;) – shx2

+0

Cảm ơn.:) Nếu tôi tìm hiểu thêm, tôi sẽ đăng lại. – Glenn

+0

Cập nhật: https://groups.google.com/forum/?fromgroups#!topic/boto-users/YiPAOvxIrUY – Glenn

2

Tôi đã đấu tranh với vấn đề này trong một thời gian, chạy các quy trình chạy dài mà đọc số lượng lớn dữ liệu từ S3. Tôi quyết định đăng giải pháp của tôi ở đây, cho hậu thế.

Trước hết, tôi chắc chắn rằng bản hack được trỏ tới bởi @Glenn hoạt động, nhưng tôi đã chọn không sử dụng nó vì tôi cho rằng nó xâm nhập (hacking httplib) và không an toàn (nó trả lại một cách mù quáng những gì nó có, tức là return e.partial, mặc dù thực tế nó có thể là trường hợp lỗi thực).

Đây là giải pháp cuối cùng tôi đã đưa ra, có vẻ như đang hoạt động.

Tôi đang sử dụng chức năng thử lại mục đích chung này:

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('operation failed (%s) with error [%s]. will retry %d more times', func, e, num_retries - i - 1) 
      if on_retry is not None: 
       on_retry() 
      if sleep is not None: 
       time.sleep(sleep) 
    assert 0 # should not reach this point 

Bây giờ, khi đọc một tập tin từ S3, Tôi đang sử dụng chức năng này, mà trong nội bộ thực hiện lần thử lại trong trường hợp IncompleteRead lỗi. Khi có lỗi, trước khi thử lại, tôi gọi key.close(fast = True).

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 (fast=True so it doesn't attempt to read remaining) 
     on_retry = lambda: key.close(fast = True) 
    ) 
+1

chỉ fyi, vấn đề được nêu tại https://github.com/boto/boto/issues/2204 – Glenn

Các vấn đề liên quan