2017-03-02 43 views
1

假设我已经使用下面的命令复制一个对象到谷歌云存储桶:是“云中”gsutil cp的一个原子操作吗?

gsutil -h "Cache-Control:public,max-age=3600" cp -a public-read a.html gs://some-bucket/ 

我现在想“在云中”复制该文件,同时保持公共ACL,并同时更新缓存控制标题:

gsutil -h "Cache-Control:no-store" cp -p gs://some-bucket/a.html gs://some-bucket/b.html 

此操作是否为原子?即我可以肯定,对象gs://some-bucket/b.html将首先与修改后的Cache-Control:no-store标题一起提供?

我的问题的原因是:我使用Google Cloud Storage存储桶作为CDN后端。虽然我希望根据Cache-Control标头中提供的max-age缓存CDN中的大部分对象,但我想确保一些特定文件(实际上是可缓存版本的副本)是从不缓存由CDN提供。因此,至关重要的是,这些对象在复制时不会以Cache-Control:public,max-age=XXX出现,而会立即以Cache-Control:no-store标题出现,以消除来自CDN的请求在某个时间点读取复制对象的可能性,其中max-age会仍然存在,因此缓存应该永远不会被缓存的对象。

回答

2

是的,使用缓存控制集复制到新对象将是原子的。您可以通过查看对象的metageneration属性来验证这一点。

例如,上传的对象:

$ BUCKET=mybucket 
$ echo foo | ./gsutil cp - gs://$BUCKET/foo.txt 
Copying from <STDIN>... 
/[1 files][ 0.0 B/ 0.0 B]             
Operation completed over 1 objects. 

,你会看到它的初始metageneration为1:

$ ./gsutil ls -L gs://$BUCKET/foo.txt | grep Meta 
    Metageneration:   1 

当一个对象的元数据被修改时,metageneration改变。例如,如果缓存控制以后,像这样更新:

$ ./gsutil setmeta -h "Cache-Control:no-store" gs://$BUCKET/foo.txt 
Setting metadata on gs://mybucket/foo.txt... 
/[1 objects]                 
Operation completed over 1 objects. 

新metageneration为2:现在

​​3210

,如果我们运行的复制命令:

$ ./gsutil -h "Cache-Control:no-store" cp -p gs://$BUCKET/foo.txt gs://$BUCKET/bar.txt 
Copying gs://mybucket/foo.txt [Content-Type=application/octet-stream]... 
- [1 files][ 4.0 B/ 4.0 B]             
Operation completed over 1 objects/4.0 B. 

的新对象的代理是1:

$ ./gsutil ls -L gs://$BUCKET/bar.txt | grep Meta 
    Metageneration:   1 

这意味着该对象只写了一次,并且自此以后未被修改。