复合对象和并行上传

为了支持并行上传和有限的附加/修改功能,Cloud Storage 可让用户将多达 32 个现有对象组合成一个新对象,而无需传输其他对象数据。

组合操作

组合操作会创建一个新对象,其内容由一系列指定序列的源对象(最多 32 个对象)串联而成。源对象必须都属于相同的存储类别,并且都存储在同一个存储分区中。源对象本身可以是复合对象。

源对象不受合成过程的影响,并且生成的复合对象也不会因源对象被替换或删除而改变。

组件计数属性

每个对象都维护着一个组件计数属性,该属性指定了创建该对象时所使用的原始上传对象的数量。您可以将一系列对象组合成一个新对象,新对象的组件计数等于此序列中每个复合对象的组件计数总和再加上此序列中的非复合对象数量。例如,当您执行组合操作时,如果前两个组件是非复合对象,而第三个组件是复合对象且组件计数为 12,则组合操作的总组件计数应为 14。

虽然复合对象可以包含的组件数量没有限制,但对象的 componentCount 元数据属性会在值为 2,147,483,647 时达到饱和。例如,假设您有一个包含 3,000,000,000 个组件的对象。在这种情况下,对象的 componentCount 值为 2,147,483,647。

复合对象完整性检查

Cloud Storage 采用的是 CRC32C,它不仅用于在上传时对每个组件对象执行完整性检查,还可让调用者在下载生成的复合对象时对其执行完整性检查。CRC32C 是一种错误检测代码,可根据各个组件的 CRC32C 值进行高效计算。您的应用在使用 CRC32C 时应遵循以下几点:

  • 上传组件对象时,您应使用 CRC32C 库(如下面列出的其中一个库)计算每个对象的 CRC32C 值,并将该值包含在请求中。
  • 对于组合操作,您应将 CRC32C 包含在请求中。Cloud Storage 将使用复合对象的 CRC32C 进行响应。Cloud Storage 不会计算复合对象的 MD5 值。
  • 下载时,您应计算所下载对象的 CRC32C 值,并将所得结果与响应中包含的值进行比较。
  • 如果您的应用可能会在组件对象的上传到组合这段时间内更改这些对象,您应为源对象指定特定于代次的名称,以避免出现争用情况。

用于计算 CRC32C 值的库包括 Boost(适用于 C++)、GoogleCloudPlatform crc32c(适用于 Java)、crcmod(适用于 Python)和 digest-crc(适用于 Ruby)。另请注意,最新 Intel CPU 硬件支持 CRC32C。

过去,Cloud Storage 使用 MD5 来构建 ETag 值。这不适用于复合对象;客户端代码不应对复合对象 ETag 做任何假定,除了这些值会随着基础对象的更改而变化(请参阅面向 HTTP/1.1 的 IETF 规范)。

并行上传

您可以在并行上传对象时采用对象组合:只需将数据划分为多个区块,将每个区块并行上传到不同的对象,组合成最终对象,然后删除任何临时对象。

为了防止组件对象在上传请求和复合请求之间发生更改,用户应为每个组件提供一个预期的代次号。如需详细了解对象代次,请参阅代次与先决条件

有限的附加和修改功能

您还可以使用组合操作来完成有限的对象附加和修改操作。

附加操作的实现方式是,将数据上传至一个新的临时对象,对要执行附加操作的对象以及此新数据进行组合,(可选)按照与原始对象相同的名称来命名组合操作的输出,然后删除此临时对象。

您还可以使用组合功能来为基本的对象修改操作提供支持。例如,您可以使用序列 {Y1, Y2, Y3} 构成一个对象 X,替换 Y2 的内容,然后使用相同组件重构 X。请注意,此操作需要保留 Y1Y2Y3,因此您将需要为这些组件以及复合对象支付费用。

使用 gsutil 执行对象组合

gsutil 支持使用 compose 命令执行对象组合。如需了解详情,请运行以下命令来查看其内置文档:

gsutil help compose

例如,要将三个对象(component-obj-1component-obj-2component-obj-3)组合成一个对象 (composite-object),您可以使用以下命令:

gsutil compose gs://example-bucket/component-obj-1 gs://example-bucket/component-obj-2 gs://example-bucket/component-obj-3 gs://example-bucket/composite-object

或者,如果您只想将带有 component-obj- 前缀的对象组合在一起,那么您还可以在 compose 命令中使用通配符,如以下示例所示:

gsutil compose gs://example-bucket/component-obj-* gs://example-bucket/composite-object

组合操作完成后,您可以使用以下命令查看组件计数:

gsutil stat gs://example-bucket/composite-object

在本例中,组件计数为 3 。

以下两个命令先将 composite-object 复制到 new-object,然后再将 new-object 移回原位以使用原始名称。这两个命令均使用了 cp 命令的 -p 选项,因此 gsutil 会保留对象 ACL。

gsutil cp -D -p gs://example-bucket/composite-object gs://example-bucket/new-object
gsutil mv -p gs://example-bucket/new-object gs://example-bucket/composite-object

使用 XML API 执行对象组合

使用 XML API 组合对象的方法是,使用 compose 查询参数发出 PUT 对象请求,并加入按顺序列出组件对象名称的 XML 正文,如以下示例所示。

PUT /example-bucket/composite-object?compose HTTP/1.1
Host: storage.googleapis.com
Content-Length: 153
Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg

<ComposeRequest>
  <Component>
    <Name>component-obj-1</Name>
  </Component>
  <Component>
    <Name>component-obj-2</Name>
    <Generation>1361471441094000</Generation>
  </Component>
  <Component>
    <Name>component-obj-3</Name>
    <IfGenerationMatch>1361471441094000</IfGenerationMatch>
  </Component>
</ComposeRequest>

没有指定组件对象存储分区的原因是,如先前所述,源对象和目标对象必须都位于相同存储分区中。

上面的示例请求还指定了 component-obj-2 的代次号,因此该请求将构成这一对象的代次 1361471441094000,即使它已不是当前代次。

第三个组件是以使用 IfGenerationMatch 请求元素的条件代次形式提供的;如果指定代次号不代表组件的当前代次,将会导致请求失败。

上述对象组合请求的响应类似如下所示:

Server: HTTP Upload Server Built on Mar 6 2013 16:24:27 (1362615867)
ETag: "-CKicn4fknbUCEAE="
x-goog-generation: 1362768951202000
x-goog-metageneration: 1
x-goog-hash: crc32c=fbWtZQ==
x-goog-component-count: 3
Vary: Origin
Date: Fri, 08 Mar 2013 18:55:51 GMT
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 0
Content-Type: text/html; charset=UTF-8

x-goog-hash 标头报告对象的 CRC32C 值,您可以对该值进行验证,方法是根据用于构成该对象的 CRC32C 值构建新的 CRC32C 值。

新复合对象的组件计数是 x-goog-component-count 响应标头的值。

使用 JSON API 执行对象组合

使用 JSON API 组合对象的方法是,在 JSON 正文中按顺序列出组件对象名称,然后使用此正文发出 compose 请求,如以下示例所示。

POST /storage/v1/b/example-bucket/o/composite-object/compose
Host: www.googleapis.com
Content-Length: 216
Content-Type: application/json
Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg

{
  "sourceObjects": [
    {
      "name": "component-obj-1"
    },
    { "name": "component-obj-2"
    },
    { "name": "component-obj-3"
    }
  ],
  "destination": {
   "contentType": "application/octet-stream"
 }
}

上述对象组合请求的响应会包含一项提供了组件计数的对象资源

{
 "kind": "storage#object",
 "id": "bucket/composite-object/1388778813188000",
 "selfLink": "https://www.googleapis.com/storage/v1/b/example-bucket/o/composite-object",
 "name": "composite-object",
 "bucket": "bucket",
 "generation": "1388778813188000",
 "metageneration": "1",
 "contentType": "application/octet-stream",
 "updated": "2014-01-03T19:53:33.188Z",
 "size": "524052",
 "mediaLink": "https://www.googleapis.com/download/storage/v1/b/example-bucket/o/composite-object?generation=1388778813188000&alt=media",
 "crc32c": "V9kcXg==",
 "componentCount": 3,
 "etag": "CKDP057k4rsCEAE="
}

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Cloud Storage
需要帮助?请访问我们的支持页面