6

我有将文件写入 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()错误消失

4

1 回答 1

19

我在最新的 boto 源代码中找不到该错误消息,所以很遗憾我无法告诉您是什么原因造成的。最近,我们在不打电话的时候遇到了问题conn.close(),所以肯定至少有一种情况你必须关闭连接。这是我对正在发生的事情的理解:

S3Connection(好吧,它的父类)透明地处理几乎所有的连接细节,你不应该考虑关闭资源、重新连接等。这就是为什么大多数教程和文档都没有提到关闭资源的原因。事实上,我只知道一种应该明确关闭资源的情况,我在底部进行了描述。继续阅读!

在幕后,boto 使用httplib。此客户端库支持 HTTP 1.1 Keep-Alive,因此它可以而且应该保持套接字打开,以便它可以通过同一连接执行多个请求。

AWS 将关闭您的连接(套接字)有两个原因:

  1. 根据 boto 源代码,“AWS 在三分钟后开始超时。” 大概“事物”意味着“空闲连接”。
  2. 根据使用 Amazon S3 的最佳实践,“S3 在关闭连接之前最多可以接受 100 个请求(导致‘连接重置’)。”

幸运的是,boto 通过在三分钟结束之前回收陈旧的连接来解决第一种情况。不幸的是,boto 并没有如此透明地处理第二种情况:

当 AWS 关闭连接时,您的连接结束进入 CLOSE_WAIT,这意味着套接字正在等待应用程序执行 close()。S3Connection 如此透明地处理连接细节,以至于您实际上无法直接执行此操作!最好从一开始就防止它发生。

因此,回到最初的问题,即何时需要显式关闭,如果您的应用程序运行很长时间,长时间保持对(重用)boto 连接的引用,并通过该连接发出许多 boto S3 请求(从而触发 AWS 对套接字的“连接重置”),那么您可能会发现越来越多的套接字处于 CLOSE_WAIT 状态。您可以通过调用在 linux 上检查这种情况netstat | grep CLOSE_WAITconnection.close为防止这种情况发生,请在发出 100 个请求之前显式调用 boto 。我们在一个长期运行的过程中发出数十万个 S3 请求,并且我们connection.close在每 80 个请求之后调用。

于 2014-07-25T15:04:03.623 回答