我目前使用 WebFaction 进行托管,其基本包为我们提供了 80MB RAM。除了备份之外,这足以满足我们目前的需求。我们每天对 S3 进行一次备份。
备份过程是这样的:将数据库、tar.gz所有文件转储到一个以正确的备份日期命名的备份中,使用Amazon提供的python库上传到S3。
不幸的是,(尽管我不确定)我的读取文件的代码或 S3 代码正在将整个文件加载到内存中。由于该文件大约为 320MB(用于今天的备份),因此仅使用大约 320MB 来进行备份。这会导致 WebFaction 退出我们的所有进程,这意味着备份不会发生,我们的网站也会瘫痪。
所以这就是问题:有没有办法不将整个文件加载到内存中,或者是否有任何其他 python S3 库在 RAM 使用方面更好。理想情况下,最多需要大约 60MB!如果无法做到这一点,我如何分割文件并上传单独的部分?
感谢您的帮助。
这是导致进程退出的代码部分(在我的备份脚本中):
filedata = open(filename, 'rb').read()
content_type = mimetypes.guess_type(filename)[0]
if not content_type:
content_type = 'text/plain'
print 'Uploading to S3...'
response = connection.put(BUCKET_NAME, 'daily/%s' % filename, S3.S3Object(filedata), {'x-amz-acl': 'public-read', 'Content-Type': content_type})
最佳答案
有点晚了,但我必须解决同样的问题,所以这是我的答案。
简短回答:在 Python 2.6+ 中是的!这是因为 httplib
从 v2.6 开始支持类文件对象。所以你所需要的只是......
fileobj = open(filename, 'rb')
content_type = mimetypes.guess_type(filename)[0]
if not content_type:
content_type = 'text/plain'
print 'Uploading to S3...'
response = connection.put(BUCKET_NAME, 'daily/%s' % filename, S3.S3Object(fileobj), {'x-amz-acl': 'public-read', 'Content-Type': content_type})
长答案...
S3.py
库使用 python 的 httplib
来执行其 connection.put()
HTTP 请求。您可以在源代码中看到它只是将 data
参数传递给 httplib
连接。
来自S3.py
...
def _make_request(self, method, bucket='', key='', query_args={}, headers={}, data='', metadata={}):
...
if (is_secure):
connection = httplib.HTTPSConnection(host)
else:
connection = httplib.HTTPConnection(host)
final_headers = merge_meta(headers, metadata);
# add auth header
self._add_aws_auth_header(final_headers, method, bucket, key, query_args)
connection.request(method, path, data, final_headers) # <-- IMPORTANT PART
resp = connection.getresponse()
if resp.status < 300 or resp.status >= 400:
return resp
# handle redirect
location = resp.getheader('location')
if not location:
return resp
...
如果我们看一下 python httplib documentation我们可以看到...
HTTPConnection.request(method, url[, body[, headers]])
This will send a request to the server using the HTTP request method method and the selector url. If the body argument is present, it should be a string of data to send after the headers are finished. Alternatively, it may be an open file object, in which case the contents of the file is sent; this file object should support fileno() and read() methods. The header Content-Length is automatically set to the correct value. The headers argument should be a mapping of extra HTTP headers to send with the request.
Changed in version 2.6: body can be a file object.
关于python - Python 中的 S3 备份内存使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2464685/