我有一堆存储桶,当文件上传时,它们会向Pub/Sub主题发布通知。然后,我有一个订阅了Pub/Sub主题的云函数,它将这些文件复制到它们的最终目标桶中。这一切对大多数文件来说都很好,但当我有大文件(>1GB(时,它们无法复制。源bucket是多区域的,目标bucket是区域的和近线的。
我的代码本质上是:
client = storage.Client()
src_bucket = client.get_bucket(src_bucket_name)
src_blob = src_bucket.get_blob(src_filename)
dst_bucket = client.get_bucket(dst_bucket_name)
dst_blob = dst_bucket.blob(dst_filename)
dst_blob.rewrite(src_blob)
最初,云功能在60秒时超时,所以我认为这是问题所在,但后来我将云功能超时时间提高到540秒,但该功能仍然超时。我有一个重试20分钟的功能,这样我就可以看到问题是可重复的。在提升云功能超时失败后,我阅读了blob文档,发现blob.rewrite也有60秒的默认超时,所以我也将其提升到了540秒,但仍然超时。
在这一点上,我不确定我错过了什么。这是超时问题吗?或者这与Pub/Sub发布多条消息有关,这样我就可以让多个云功能同时制作同一个副本?或者有更好的方法可以自动在存储桶之间移动大文件吗?
首先,了解一下幕后发生的事情:
GCS的重写操作为在线操作。当重写请求确认成功时,重写已经完成,并且新操作准备就绪。不利的一面是,在复制完成时,用户必须打开重写连接。不过,这种联系不会永远持续下去。如果操作要花费超过30秒左右的时间,那么重写请求可能会以不完整结束。在这种情况下,它将返回一个重写令牌,客户端必须使用该令牌来恢复请求,否则将不会有进一步的进展。
在Python中,它看起来像这样:
rewrite_token = ''
while rewrite_token is not None:
rewrite_token, bytes_rewritten, bytes_to_rewrite = dst_blob.rewrite(
src_blob, token=rewrite_token)
print(f'Progress so far: {bytes_rewritten}/{bytes_to_rewrite} bytes.')
对于较小的对象,或者对于服务不需要做任何工作来移动数据的对象,这都无关紧要。不过,对于大型操作,您需要检查是否需要恢复。
也就是说,我不希望从您的代码中看到超时。这是另一种失败。你确定你得到的错误是超时吗?
我在代码的第2行和第4行注意到,在GCP文档中有client.get_bucket
-,他们没有提到get_bucket
方法:https://cloud.google.com/storage/docs/renaming-copying-moving-objects#storage-复制对象python
(你必须点击"代码示例"选项卡,然后选择"Python"来查看我在说什么。(
您的代码在您自己的Python环境中本地工作吗?我知道,这是个愚蠢的问题,但有时人们只是直接去云端。\_(ツ)_/