python - Python 中的 S3 备份内存使用情况

标签 python memory upload amazon-s3

我目前使用 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/

相关文章:

python - 如何使用变量作为列表索引?

python - 从列表中的字符串创建字典?

python - 当我不能使用 self 时如何上课 - Python

c++ - 重载 >> 动态 c 字符串类的运算符

http - Google Cloud Storage 签名 URL——如何指定最大文件大小?

python - 使用 Python 运行可执行文件并填写用户输入

Java 应用程序存在大量内存问题

java - 如何查找 Java 内存泄漏

php - 使用 php 直接写入磁盘

android - 无需确认即可将 SQLite 数据库同步到谷歌驱动器