我有将文件写入s3的代码。代码工作正常
conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.get_bucket(BUCKET, validate=False)
k = Key(bucket)
k.key = self.filekey
k.set_metadata('Content-Type', 'text/javascript')
k.set_contents_from_string(json.dumps(self.output))
k.set_acl(FILE_ACL)
这工作得很好。然后我注意到我没有关闭我的连接,所以我在最后添加了这一行:
conn.close()
现在,文件像以前一样写但是,我现在在日志中看到这个错误
S3Connection instance has no attribute '_cache', unable to write file
任何人都能看到我在这里做错了什么或知道是什么导致了这个?我注意到boto上的所有教程都没有显示人们关闭连接,但我知道你应该关闭你的IO操作连接作为一般规则......
修改
关于这一点的说明,当我评论conn.close()
时,错误消失
答案 0 :(得分:16)
我在最新的boto源代码中找不到该错误消息,所以很遗憾我无法告诉你是什么导致它。最近,当我们没有调用conn.close()
时,我们遇到了问题,所以肯定至少有一种情况你必须关闭连接。以下是我对正在发生的事情的理解:
S3Connection(嗯,它的父类)透明地处理几乎所有的连接细节,你不必考虑关闭资源,重新连接等。这就是大多数教程和文档没有提到关闭资源的原因。事实上,我只知道一种情况,你应该明确地关闭资源,我在底部描述。请继续阅读!
在封面下,boto使用httplib。此客户端库支持HTTP 1.1 Keep-Alive,因此它可以并且应该保持套接字打开,以便它可以通过同一连接执行多个请求。
AWS将关闭您的连接(套接字)有两个原因:
幸运的是,boto通过在三分钟之前完成回收陈旧连接来解决第一种情况。不幸的是,boto并没有如此透明地处理第二种情况:
当AWS关闭连接时,您的连接结束进入CLOSE_WAIT,这意味着套接字正在等待应用程序执行close()。 S3Connection透明地处理连接细节,您实际上无法直接执行此操作!最好先防止它发生。
因此,回到原来的问题,当你需要明确关闭时,如果你的应用程序运行了很长时间,长时间保持对(重用)boto连接的引用,并使许多boto S3请求结束该连接(因此通过AWS触发套接字上的“连接重置”),然后您可能会发现越来越多的套接字在CLOSE_WAIT中。你可以通过调用netstat | grep CLOSE_WAIT
在linux上检查这个条件。为了防止这种情况,请在发出100个请求之前显式调用boto的connection.close
。我们在长时间运行的过程中生成了数十万个S3请求,并且在每个请求之后调用connection.close
。