Cloudflare
KV
R2
Cache API
Armazenamento

KV、R2 与 Cache API:何时使用每个 Cloudflare 存储层

Cloudflare KV、R2 和 Cache API 之间的技术和经济比较:架构、成本模型、正确用例和常见反模式。

KV、R2 与 Cache API:何时使用每个 Cloudflare 存储层

Cloudflare 的三个存储原语(KV、R2 和 Cache API)一起出现在文档中并共享相同的运行时,这给人的印象是它们是同一问题的替代方案。他们不是。每个都是采用不同的架构、针对不同的工作负载和不同的成本模型构建的。使用错误的方法不仅效率低下:在某些情况下,它根本不起作用。

这种混乱是可以理解的。所有这三个“存储数据”。但相关的区别并不是它们在抽象中所做的事情,而是它们在实际流量下的表现、它们的规模成本以及它们提供的保证。

KV:小型、频繁读取数据的全局存储

KV 是一个全球分布式的键值存储。写入将发送到中央存储并在最多 60 秒内传播到 300 多个 PoP。如果密钥缓存在最近的 PoP 中,则读取会在亚毫秒内到达;如果需要从中央存储中获取密钥,则大约需要 20 毫秒。

成本模式有利于批量阅读:每月免费阅读前 1000 万次之后,每百万次阅读 0.50 美元。写入成本同样为每百万 0.50 美元,但只有 100 万是免费的。每个值的最大限制为 25MB。

KV 非常适合很少写入和大量读取的数据:产品配置、[功能标志2、模板、内容索引、带有 TTL 的会话令牌。它对于频繁更改或需要立即一致性的任何内容都效果不佳 - 长达 60 秒的窗口的最终一致性以及缺乏原子操作是真正的限制,而不是文档细节。

R2:无出口费用的对象存储

R2是Cloudflare的对象存储,功能相当于S3。它是为大型文件(图像、视频、备份、数据导出、静态资产)而构建的。与 S3 相关的竞争差异在于没有出口费用:您无需支付将数据从 R2 传输到互联网的费用,这在 S3 中是账单上最痛苦的行之一。

存储成本为每月 0.015 美元/GB。 R2 中的每个读取操作 (GET) 都算作一个请求 - 没有像 KV 那样的全局自动缓存。如果您在每个 Worker 请求中 GET 一个 R2 对象,则您需要为每个请求加上每个 GET 的延迟时间付费。这使得 R2 不适合每个请求的高读取频率数据。

正确的组合是对文件使用 R2,对索引或缓存版本使用 KV(或缓存 API)。提供图像服务的 Worker 可以将二进制文件存储在 R2 中,并在 KV 中维护带有签名 URL、元数据和 HTTP 标头的 JSON,因此频繁的读取会在亚毫秒内访问 KV,而 R2 仅用于上传和生成 URL。

R2 中每个对象的限制与 KV 中的不同:支持多个 GB 文件。对于每个值最大为 25MB 的 KV,R2 是任何超过此阈值的数据的自然目的地。

缓存 API:每个 PoP 的 HTTP 响应缓存

Cache API 将 0 对象存储在当前 PoP 的 HTTP 缓存中。它是免费的,没有操作配额,并且作为 HTTP 响应的缓存层运行,而不是作为共享状态存储。

它与 KV 的区别在于范围:缓存 API 是针对每个 PoP 的,而不是全局的。圣保罗 PoP 中的缓存命中不会影响法兰克福 PoP。如果法兰克福的工作人员从未收到对该 URL 的请求,则法兰克福的缓存将处于冷状态,无论圣保罗从缓存中提供该响应多少次。

另一个限制:由于 LRU 压力,Cache API 中的内容可能随时被 PoP 驱逐。无法保证请求之间的持久性 - 对同一资源的下一个请求可能会遇到冷缓存,即使前一个请求已填充它。

缓存 API 非常适合在短时间内对第三方 API 的请求进行重复数据删除 — 您获取一次,将 1 缓存 30 秒,并且同一 PoP 中的后续请求将重用该响应,而无需调用上游 API。它还用于缓存同一 PoP 中突发请求的计算成本高昂的响应。

什么不起作用:使用 Cache API 作为 Workers 之间或区域之间的共享状态。不同 PoP 中的两个 Worker 实例不会看到相同的缓存状态。对于共享状态,KV 就是方法。

反模式矩阵

使用 R2 进行应用程序配置是来自 S3 的团队中最常见的错误。在 S3 上,通常将 config.json 存储在存储桶中并在应用程序启动时读取它 - 服务器持续数小时或数天,因此每次重新启动时执行 GET 都很便宜。在 Workers 中,每个隔离区都可以频繁创建和销毁。每个 GET 到 R2 都有网络请求的延迟,并算作收费操作。对于配置,具有模块级缓存的 KV 是正确的模型。

对视频文件或大型数据集使用 KV 是另一个极端。每个值 25MB 的限制已经给任何实际大小的资产带来了直接的问题。但超出限制后,对于通过用户频繁上传到达的文件来说,写入 KV 的成本过高。 R2 的价格为每月 0.015 美元/GB,对于大文件存储来说便宜了几个数量级。

对需要在 PoP 之间保持一致的任何类型的状态使用 Cache API 肯定会导致不稳定行为。典型的症状是“有时”出现的错误 - 因为为前一个请求提供服务的 PoP 已填充缓存,而为该请求提供服务的 PoP 没有填充缓存。缓存 API 不会取代全局数据的 KV。

如何选择

该决定从数据类型和访问频率开始。小数据,每秒读取多次,需要全局分布:KV。大文件,通过上传写入并以中低频率读取:R2。很少改变的 HTTP 响应,可能是 PoP 本地的:缓存 API。

成本确认或放弃选择。如果写入量很大,KV 就会变得昂贵。如果每个文件的单独 GET 量很大,R2 就会变得昂贵且缓慢。如果你需要跨 PoP 一致性,Cache API 就不行。

将三者结合起来就是正确的模型

在带有 Workers 的成熟架构中最常出现的模式是刻意的组合。 R2 存储二进制文件。 KV 存储索引、元数据和短期签名 URL。缓存 API 对同一 PoP 的突发请求进行重复数据删除。每层都执行其设计目的,结果是一个性能良好且成本合理的存储堆栈。

该陷阱试图简化为单个原语。 Cloudflare 提供这三种方案,因为每种方案解决不同的问题。了解它们之间的界限是将在开发中有效的实现与在实际流量中生存的实现区分开来的。

另请阅读

  • [Cloudflare KV:当你需要写时,全球分布式意味着什么3
  • 【KV中的缓存失效:没有人优雅解决的问题4
  • [Cloudflare 负载均衡和地理转向:当 DNS 成为智能流量层5
  • [生产中的 KV:有效的模式和一开始就具有误导性的模式6
  • [速率限制、功能标志和分布式配置的 KV:它在哪里工作以及在哪里中断7
  • [Workers + D1 + KV + R2:在同一服务中组合绑定8