Origin Range Requests: Serving large files without range-request tuning
TL;DR · AI 摘要
Origin Range Requests: Serving large files without range-request tuning Cloudflare Blog post Product News Storage Cache...
核心要点
- 主题聚焦:Origin Range Requests: Serving large files witho
- 来源:The Cloudflare Blog,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
Origin Range Requests: 无需调整范围请求即可传输大文件 | Cloudflare 博客
post
产品动态
存储
缓存
性能
Pingora
2026年10月23日
Origin Range Requests:无需调整范围请求即可传输大文件
Matthew Gumport
9分钟阅读
复制链接
一个视频播放器跳转到电影中间时,会请求几兆字节的数据。在我们旧的范围缓存机制下,这个请求可能导致 Cloudflare 从源站拉取 128 MiB 数据,并在数据中心之间传输,有时甚至在观众离开后仍在进行。范围请求是传输大文件的方式,但粗略地缓存它们会导致大规模 CDN 运营时出现网络带宽浪费和磁盘操作浪费。
因此我们重新设计了缓存处理方式。对于 R2(Cloudflare 的对象存储),p99 首字节时间降低了约 50%,后续优化又使 R2 和类似工作负载的分级缓存流量减少了约 6%。
今天,我们以「Origin Range Requests」的形式开放这一新实现,作为所有计划均可自助使用的功能。无需调整范围大小,也无需联系支持团队。只需通过缓存规则启用即可,Cloudflare 会处理其余部分。
请求文件的一部分
HTTP 范围请求会请求资源的一部分而非整个资源。客户端发送带有 Range 头的普通 GET 请求:
GET /movie.mp4 HTTP/1.1
Host: example.com
Range: bytes=1048576-2097151如果服务器支持该请求,会返回 206 Partial Content 状态码,并通过 Content-Range 标识返回的字节范围:
HTTP/1.1 206 Partial Content
Content-Range: bytes 1048576-2097151/524288000
Content-Length: 1048576范围请求在处理大文件时非常常见。视频播放器可以请求跳转位置附近的字节而非整个文件,下载管理器可以在中断后恢复下载,包管理器可以获取工件的一部分,客户端可以在下载整个文件前检查文件末尾。
客户端决定是否发起范围请求,Cloudflare 不会修改该请求。相反,Origin Range Requests 改变了 Cloudflare 满足该请求的方式。
范围大小问题
Cloudflare 通过静态区域配置支持范围请求缓存多年。
之前的实现类似于 nginx 博客文章中描述的缓存切片方式:每个客户端请求都会映射到文件的固定大小范围,范围大小和文件扩展名按区域配置。
每个范围的大小带来了权衡:小范围会导致大量小的源站请求,以及 Cloudflare 在内存中合并所有请求时产生的内存压力;大范围则会导致 Cloudflare 下载比客户端请求多得多的数据。范围大小本身的更新会失效缓存条目,因为大小是缓存键的一部分。
这种设计还意味着通过我们的网络请求内容的人在访问这些文件时可能会有糟糕的体验。即使客户端请求的范围相距很远,只要落在同一范围内,并发请求可能会相互阻塞。基于 nginx 的缓存也无法将范围缓存与并发流式传输结合使用——这是我们构建的一项功能,允许多个客户端在文件仍在写入时从缓存中读取。同时开启这两个功能会导致响应被截断,每个范围必须完全下载后才能被读取,热门文件需要为每个范围进行单独的源站获取。
这些额外字节可能还会跨越我们分布式缓存的多个部分:从源服务器到一个数据中心,缓存层级之间,然后传输到客户端。每经过一次中转,浪费都会成倍增加。没有一个统一的值能同时适用于小范围请求、顺序下载、大型媒体文件,以及每种源服务器和缓存拓扑结构。
我们的内部缓存限制会直接暴露给客户,而客户并不需要深入理解我们的能力就能高效地获取文件。
幸运的是,我们从nginx迁移到基于Pingora的缓存服务器,这为我们解决困扰客户、难以使用的配置设置提供了机会。
固定大小的缓存块
解决方案来自于Pingora已经实现的功能。为了便于恢复中断的下载,它会将每个缓存文件以固定大小的块存储在磁盘上。如果缓存本身已经以块为单位进行处理,那么范围大小根本不需要作为配置项存在,直接使用块大小即可!
对于范围请求,Cloudflare会检查哪些请求的字节已经被缓存。它会直接返回这些已缓存的字节。对于缺失的字节,它会从源服务器获取与缓存固定块边界对齐的范围,将结果存储在与普通缓存存储相同的块中,并只返回客户端请求的字节。
例如,请求字节150-250时,可能会导致Cloudflare获取包含这些字节的对齐块。下游响应仍然只包含150-250字节。
这并不能消除小于我们块大小的请求带来的额外工作——此类请求仍可能需要获取包含它的整个块。我们也会为非对齐范围承担额外的工作成本。不同之处在于,这些额外工作是有限且可预测的,不再由客户选择的范围大小决定,而客户选择的范围大小可能会对我们和源服务器产生不可预测的影响。
协调缓存数据和传输中数据
解析Range头是相对简单的。更困难的问题是当请求的字节跨越缓存数据、源服务器响应和正在进行的下载时,如何生成一个正确的响应。
从高层来看,边缘节点:
- 查找资产头信息和范围覆盖元数据
- 从磁盘或内存流中读取尽可能多的资产部分
- 使用对齐范围从源服务器获取缺失的覆盖范围
- 将新字节写入缓存并记录完成的范围到元数据中
- 将各部分组合起来,并为客户端响应设置Content-Range和Content-Length
这是一个协调器,而不是单次缓存查询。一个请求可能同时使用缓存的前缀、正在进行的下载和新获取的后缀。内部源服务器响应可能比下游响应更大,但下游状态和头信息只描述请求的范围。
如果现有下载覆盖了另一个请求的字节,第二个请求可以附加到该下载而不是启动新的源服务器获取。这在热门大文件的突发访问期间可以共享工作负载。
该设计利用了现有的缓存数据模型。头信息标识资产版本,正文以有限块存储,元数据记录成功写入的范围。
组合前验证
只有当所有字节属于同一表示时,组合的范围响应才是有效的。协调器会验证每个源服务器响应是否匹配请求范围,总资产大小是否稳定,以及实体标签在子请求中是否保持一致。
If-Range 头允许客户端仅在表示内容仍与已知验证器匹配时请求范围。如果不匹配,Cloudflare 会返回完整的表示内容,而不是从不同版本中组合字节。
Cloudflare 还会避免对即将解压缩的表示内容进行范围组合,因为压缩字节集上的范围与解压缩响应中选择的范围会有所不同。在这些情况下,Cloudflare 会提供完整的转换后响应,而不是宣传无法正确满足的范围。
最终的行为符合标准 HTTP 协议:
- 可满足的范围会收到 206 Partial Content 响应,并附带准确的 Content-Range。
- 无法满足的范围会收到 416 Range Not Satisfiable 响应。
- 无法安全分段的响应会以完整表示内容形式提供。
生产环境的变化
在向所有人开放 Origin Range Requests 之前,我们首先将现有使用旧范围缓存功能的用户迁移至新实现,优先处理对我们的影响最大的工作负载。
这些工作负载经常针对非常大的文件发起大量并发范围请求,且流量波动剧烈。旧系统的范围大小配置从数 KB 到数十 GB 不等。大范围大小可能导致单个请求从源站下载数 DVD 量级的数据,并在多个数据中心之间传输,有时甚至在客户端已放弃并转向其他服务后仍会持续。小范围大小则会导致单个请求分解为大量微小源站请求,每个请求在等待时都会占用内存。这两种模式都曾引发实际的运营事故。
R2 是最大的内部用户,其配置的范围大小为 64 MiB,因此跨越范围边界的微小读取操作可能造成数据中心间 128 MiB 的传输开销。在将 R2 迁移至新实现后,我们观察到:
- 响应速度提升。在 R2 的存储区域中,无论是缓存命中还是未命中,p99 首字节时间都减少了约一半。
- 网络传输字节数减少。我们最近的改进使协调器能够在一个响应中将磁盘上的字节与从上游获取的字节合并。此前请求只能完全从缓存或完全从上游获取。在为 R2 启用此功能后,R2 及类似工作负载的分层缓存流量每周下降约 6%,这意味着每天减少了数 PB 的数据中心间数据传输。
入门指南
当缓存不再依赖客户选择的范围大小后,产品配置变得前所未有的简单。客户通过缓存规则选择匹配的流量,Cloudflare 负责分片和缓存协调。
Origin Range Requests 适用于客户端自然请求大型可缓存对象部分的流量场景:
- 可渐进播放和可定位的视频(如 MP4)
- 可恢复的大文件下载
- 软件分发和包仓库
- 磁盘镜像、归档文件和其他多 GB 级对象
- 需要传输大型模型文件或获取模型工件特定区域的 AI 训练和推理工作负载
- 获取元数据或大型文件小区域内容的客户端
我们计划将此功能作为某些文件类型的默认服务方式,且可通过缓存规则进行修改。
此功能不会改变常规的缓存资格。启用此功能不会使原本无法缓存的响应变得可缓存。源服务器也需要支持字节范围,才能使部分源获取具有实际意义。
要启用此功能,请创建一个匹配大文件流量的缓存规则,并将「Origin Range Requests」设置为开启状态。您可以在仪表盘的「Caching > Cache Rules」中进行设置,或通过 API 使用 origin_range_requests: { "mode": "on" } 实现。客户选择流量类型;边缘节点负责处理缓存协调和正确性需求。
table of contents column
discussion column
RELATED TAGS AND SOCIAL MEDIA LINKS
Related tags
在社交媒体上关注
- Cloudflare
EMAIL SIGNUP