Cloud Storage 的最佳做法

简介

本页面总结了从 Cloud Storage 文档中的其他页面提取的最佳做法。您可以参考本页中列举的最佳做法,了解在构建使用 Cloud Storage 的应用时的注意事项。发布商业应用时,请遵循这些最佳做法。

如果您刚开始使用 Cloud Storage,那么可能不太适合首先参考本页面,因为其中并未介绍有关如何使用 Cloud Storage 的基础知识。如果您是新用户,我们建议您首先参考使用入门:使用 GCP Console使用入门:使用 gsutil 工具

命名

  • 存储分区命名空间是全局性的,并会公开显示。每个存储分区名称在整个 Cloud Storage 命名空间中必须具有唯一性。如需了解详情,请参阅存储分区和对象命名准则

  • 如果您需要大量存储分区,请为存储分区名称使用 GUID 或等效标识,在代码中设置重试逻辑以处理名称冲突,并保留一个列表以交叉引用存储分区。另一种选择是使用域命名存储分区并将存储分区名称作为子域进行管理。

  • 不要在存储分区名称中使用用户 ID、电子邮件地址、项目名称、项目编号或任何个人身份信息 (PII),因为任何人都可以探测存储分区的存在。同样地,在将 PII 放入对象名称时要非常慎重,因为对象名称会出现在对象的网址中。

  • 存储分区名称应符合标准 DNS 命名约定,因为存储分区名称可能会作为 CNAME 重定向的一部分显示在 DNS 记录中。如需详细了解存储分区名称要求,请参阅存储分区名称要求

  • 对象中的正斜杠对于 Cloud Storage 没有特殊意义,因为系统不支持原生目录。因此,您可以实现与使用斜杠分隔符的深度嵌套目录类似的结构,但该结构的性能无法媲美可列出深度嵌套子目录的原生文件系统。

  • 如果要并行上传大量文件,请避免使用顺序文件名,例如基于时间戳的文件名。由于具有顺序名称的文件会被连续存储,因此,它们可能会访问相同的后端服务器,这意味着吞吐量将受到限制。要获得最佳的吞吐量,您可以将序列号的哈希值添加为文件名的一部分,以使其保持不连续。如需了解详情,请参阅请求率和访问权限分配准则

流量

  • 对将发送到 Cloud Storage 的流量进行粗略估计。具体来讲,请将以下指标纳入考量:

    • 每秒操作数。对于存储分区和对象以及创建、更新和删除操作而言,您期望每秒执行多少次操作。

    • 带宽。在哪个时间范围内将发送多少数据?

    • 缓存控制。在对象上指定 Cache-Control 元数据有利于减少热门对象或频繁访问对象上出现的读取延迟时间。如需了解如何设置对象元数据(例如 Cache-Control),请参阅查看和修改元数据

  • 妥善设计您的应用以最大限度减少流量高峰。如果您的应用的多个客户端要进行更新,请将更新作业分散到一天内的多个时间进行。

  • 虽然 Cloud Storage 对于请求率没有设置上限,但为了在调节到高请求率时获得最佳性能,请遵循请求率和访问权限分配准则

  • 请注意,某些操作存在速率限制,请相应地设计您的应用。

  • 如果出现错误,请使用指数退避算法以避免因大规模突发流量而导致的问题。

  • 了解客户对您的应用所期望的性能等级。 此信息将帮助您在创建新存储分区时选择存储方案和区域。

区域和数据存储方案

  • 对于将频繁传送的高可用性数据,应使用 Standard 存储空间类别。此类存储空间可提供最佳的可用性,但需要支付较高的费用。

  • 对于不经常访问且接受略低可用性的数据,您可以使用 Nearline 存储空间Coldline 存储空间类别。

  • 请将数据存储在距离应用用户最近的区域。例如,对于 EU 数据,您可以选择 EU 存储分区,对于 US 数据,您可以选择 US 存储分区。如需了解详情,请参阅存储分区位置

  • 在选择用户数据的位置时,请牢记合规要求。 用户将提供数据的位置是否存在法律要求?

安全、ACL 和访问权限控制

  • 首要预防措施是:永远不要共享您的凭据。每个用户都应具有不同的凭据。

  • 当您打印出 HTTP 协议详情时,标头中会显示您的身份验证凭据,例如 OAuth 2.0 令牌。如果您需要将协议详情发布到留言板或需要提供 HTTP 协议详情以进行问题排查,请确保清理或撤消输出中显示的所有凭据。

  • 请尽可能使用 TLS (HTTPS) 来传输数据。这可确保在通过网络传输数据时保护您的凭据和数据。例如,要访问 Cloud Storage API,您应使用 https://storage.googleapis.com。

  • 确保使用可验证服务器证书的 HTTPS 库。如果缺少服务器证书验证功能,您的应用将容易遭受中间人攻击或其他攻击。请注意,默认情况下,某些常用实现语言附带的 HTTPS 库不会验证服务器证书。例如,3.2 版之前的 Python 没有内置或完全支持服务器证书验证功能,您需要使用第三方封装容器库来确保您的应用可以验证服务器证书。默认情况下,Boto 插件包含的代码会验证服务器证书。

  • 当应用不再需要访问您的数据时,您应撤消这些应用的身份验证凭据。如果是 Google 服务和 API,您可以通过以下操作来实现此目的:登录 Google 帐号权限,点击不需要的应用,然后点击移除访问权限

  • 确保安全存储您的凭据。根据您的环境以及凭据的存储位置,您可以采用不同的方式。例如,如果您将凭据存储在配置文件中,请确保针对该文件设置适当的权限,以防发生不必要的访问。如果您使用的是 Google App Engine,请考虑使用 StorageByKeyName 存储您的凭据。

  • Cloud Storage 请求通过存储分区和对象的名称来引用存储分区和对象。因此,即使 ACL 会阻止未经授权的第三方对存储分区或对象执行操作,第三方仍可以尝试使用存储分区或对象名称发出请求,并通过观察错误响应来确定这些名称是否存在。然后,存储分区或对象名称中的信息可能会发生泄漏。如果您担心存储分区或对象名称的隐私性,应采取适当的预防措施,例如:

    • 选择难以猜测的存储分区和对象名称。例如,名为 mybucket-gtbytul3 的存储分区就具备足够的随机性,使未经授权的第三方无法轻易猜到该名称,或者难以从中枚举出其他存储分区名称。

    • 避免在存储分区或对象名称中使用敏感信息。例如,您可以将您的存储分区命名为 somemeaninglesscodename-prod,而不要将其命名为 mysecretproject-prodbucket。在某些应用中,您可能需要将敏感元数据保留在自定义 Cloud Storage 标头(例如 x-goog-meta)中,而不是将该元数据编码到对象名称中。

  • 尽量使用群组来明确列出大量用户。群组不仅可以更好地进行调节,还提供了一种非常有效的方法来同时更新大量对象的访问控制政策。此外,由于您不需要针对每个对象发出更改 ACL 的请求,采取这样的做法也会比较节省费用。

  • 在将对象添加到存储分区之前,先检查是否已按您的要求设置默认对象 ACL。这可以为您节省更新各个对象的 ACL 时所耗费的大量时间。

  • 存储分区 ACL 和对象 ACL 彼此独立,这意味着,存储分区的 ACL 不会影响该存储分区内的对象的 ACL。有可能出现这种情况:没有存储分区权限的用户拥有该存储分区内某对象的权限。例如,您可以创建一个存储分区,并只向 GroupA 授予列出存储分区中对象的权限,然后将一个对象上传到该存储分区中,并向 GroupB 授予该对象的 READ 权限。 这样一来,GroupB 将能够读取该对象,但无法查看该存储分区的内容或执行与该存储分区相关的任务。

  • Cloud Storage 访问控制系统允许您将对象指定为可供公开读取。确保您使用此权限写入的所有对象都是您计划公开的对象。一旦“发布”,互联网上的数据可能会被复制到许多地方,因此,实际上您无法重新掌控使用此权限写入的对象的读取权限。

  • Cloud Storage 访问控制系统允许您将存储分区指定为可被公开写入。虽然以这种方式配置存储分区可以方便地实现各种目的,但我们建议您不要使用这项权限,因为该权限可能会被滥用于分发非法内容、病毒和其他恶意软件,并且存储分区所有者对存储在其存储分区中的内容负有法律和财务上的责任。

    如果您需要以安全的方式向没有 Google 帐号的用户提供内容,我们建议您使用签名网址。例如,您可以使用签名网址提供对象的链接,而您的应用客户无需向 Cloud Storage 进行身份验证即可访问该对象。创建签名网址时,您可以控制访问权限的类型(读取、写入、删除)和持续时间。

  • 如果您使用 gsutil,请参阅其他建议

上传数据

  • 如果您使用 XMLHttpRequest (XHR) 回调来获取进度更新,请不要在检测到进度停止时将连接关闭并重新打开。否则会在网络拥塞期间产生错误的正反馈环。 当网络出现拥塞时,XHR 回调可能会积压在上传信息流的确认 (ACK/NACK) 活动后方,如果在这种情况下将连接关闭并重新打开,将导致占用更多的网络容量,造成您无法承受的代价。

  • 对于上传流量,我们建议您设置合理长度的超时时间。为了实现良好的最终用户体验,您可以设置一个客户端计时器;当您的应用长时间未收到 XHR 回调时,该计时器会在客户端状态窗口中更新一则消息(例如,“网络拥塞”)。发生这种情况时,不要只是关闭连接并重试。

  • 如果您使用 Compute Engine 实例,并且实例的进程通过向 Cloud Storage 发送 POST 请求来启动可续传上传,那么,您应在 Cloud Storage 存储分区所在的位置中使用 Compute Engine 实例。然后,您可以使用地理位置 IP 服务来选择将客户请求路由到的目标 Compute Engine 区域,这有助于将流量保留在本地的某个地理位置区域。

  • 对于可续传上传作业,可续传会话应保留在该会话的创建区域中。这样做可以减少在读取和写入会话状态时出现的跨区域流量,从而提高“可恢复的上传”的性能。

  • 尽可能避免将传输分成较小的数据块,而是在一个数据块中上传整个内容。避免数据分块可消除固定的延迟费用、提高吞吐量,并降低针对 Cloud Storage 的 QPS。

    在以下情形中,您应该考虑分块上传内容:动态生成源数据;客户端具有请求大小限制(许多浏览器都是如此);如果没有首先将完整请求加载到内存中,您的客户端将无法通过单一请求流式传输数据。如果您的客户端收到错误,他们可以向服务器查询提交偏移,并继续从该偏移处上传剩余的字节。

  • 请尽可能避免上传同时具有 content-encoding: gzip 和压缩的 content-type 的内容,因为这可能会导致出现意外行为

删除数据

如果您担心应用软件或用户可能在某些时候错误地删除或覆盖对象,Cloud Storage 具有可帮助您保护数据的特性:

列出对象

如果您刚从存储分区中删除了大量对象,列出对象的过程可能会暂时变得非常缓慢。这是因为,系统不会立即从底层存储系统中清除删除的记录,因此,在查找要返回的对象时,列出对象功能需要跳过已删除的记录。

最终,系统将从底层存储系统中移除已删除的记录,对象列出功能的性能将恢复正常。这通常需要几个小时的时间,但在某些情况下,可能需要数天。

您应对工作负载进行设计,以避免要列出的对象范围具有大量最近删除的对象。例如,如果您尝试以重复列出对象并进行删除的方式来删除存储分区中的对象,您应使用“列出对象”功能的响应所返回的页面令牌来发出下一个列出对象的请求,而不是从头开始为每个请求重新启动“列出对象”功能。从头开始重新启动“列出对象”功能时,每个请求都需要跳过刚刚删除的所有对象,这会导致列出对象的过程变慢。 如果您删除了使用某个前缀的大量对象,请尽量避免在删除后立即列出使用该前缀的对象。

网站托管

跨域资源共享 (CORS) 主题介绍了如何允许托管在其他网站上的脚本访问存储在 Cloud Storage 存储分区中的静态资源。与此相反的情景是,允许 Cloud Storage 中托管的脚本访问 Cloud Storage 的外部网站上托管的静态资源。在后一种情景中,该外部网站将传送 CORS 标头,以允许 storage.googleapis.com 上的内容进行访问。建议您为此类数据访问提供专属的特定存储分区。例如,最好让网站传送 CORS 标头 Access-Control-Allow-Origin: https://mybucket.storage.googleapis.com,而不是 Access-Control-Allow-Origin: https://storage.googleapis.com。 这种做法可防止您的网站在不经意间将静态资源过度公开给所有 storage.googleapis.com

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

发送以下问题的反馈:

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