使用 Zstandard 和 Pingora,我们可能节省 PB 级别的缓存存储

Hacker News Top 新闻

摘要

Cloudflare 原型化了一个名为 Cache Transcoding 的系统,该系统在 Pingora 中使用 Zstandard 压缩,通过压缩符合条件的资产来节省 PB 级别的缓存存储,实现了平均 2.8 倍的压缩率,且 CPU 开销极小。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/09/02 20:52

# 我们如何通过Zstandard与Pingora节省PB级缓存存储 来源:https://blog.cloudflare.com/cache-transcoding/ 内存成本正急剧上升。过去一年中,内存和硬盘价格均大幅上涨。在Cloudflare,我们运营着多个大规模分布式存储产品(包括著名的CDN),这些产品依赖于高效利用已部署的内存,以持续为所有客户提供服务。 基于此,我们设计了一种扩展有效缓存容量的原型方案。通过在Pingora(https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/)中使用Zstandard(https://github.com/facebook/zstd)对符合条件的资源进行编码,该架构以小幅CPU开销的增加,换取了显著的存储空间节省和跨数据中心带宽节约。 我们开发了一个名为“缓存转码”(Cache Transcoding)的原型系统,这是我在Cloudflare实习期间,作为1.1.1.1实习生计划(https://blog.cloudflare.com/cloudflare-1111-intern-program/)的一部分构建的。当符合条件的响应进入缓存时,我们会在将其写入磁盘之前,使用Zstandard(或zstd)进行编码。在资源保留在缓存中及通过分层缓存(Tiered Cache)(https://blog.cloudflare.com/tiered-cache-smart-topology/#tiered-cache)在数据中心间移动期间,我们保持这种压缩形式,然后在向客户端提供响应之前将其解码。 在初步测试中,这种编码平均将符合条件的资源磁盘占用缩减至原始大小的三分之一。我们面向源站的代理所需的额外CPU开销估计很小,但这正是权衡所在。CPU的轻微增加为Cloudflare带来了PB级的有效缓存容量,并减少了数据中心间传输的数据量。当资源进入缓存时,编码成本只需支付一次。而每次该资源被重复利用时,节省的存储和带宽效益就会持续产生。 ## 什么是Zstandard? Zstandard或zstd,是由Facebook的Yann Collet(https://engineering.fb.com/2018/12/19/core-infra/zstandard/)开发的一种无损压缩算法,于2016年开源。无损意味着解压缩后的数据与原始数据的每个字节都完全一致。我们可以改变资源在磁盘上的表示形式,而不改变资源本身。 Zstd旨在平衡压缩率和速度。在我们之前的浏览器压缩测试(https://blog.cloudflare.com/new-standards/)中,它比Brotli(https://research.google/pubs/brotli-a-general-purpose-data-compressor/)压缩速度快42%,同时生成的文件大小几乎相同;并且在速度相当的情况下,生成的文件比gzip小11.3%。这种平衡很重要,因为缓存转码会涉及大量流量,因此编码和解码都需要保持快速。 原型使用zstd级别3,在不将缓存填充变成CPU瓶颈的前提下,为我们提供了大部分压缩收益。 Cloudflare传统上使用源站提供的内容编码来存储资源。如果源站发送未压缩的响应,我们会将那些未压缩的字节存储在磁盘上,并在数据中心间以相同形式传输。缓存转码则在缓存内部增加了压缩功能。 ## 并非所有内容都值得压缩 转码并不意味着压缩所有内容。图像、视频和字体通常已经压缩过。在我们的流量样本中,这类媒体内容占21.4%的请求量,但占63.3%的数据量。再次压缩它们只会徒然消耗CPU。 可压缩的文本则不同。HTML、JSON、CSS和JavaScript占了67.3%的请求量和22.3%的数据量。在这个文本类别中,大约71%的`Content-Encoding`未设置(即未压缩),并且它们具有良好的压缩效果。 在我们的受控测试集中,符合条件的资源被压缩了大约2.8倍。 **指标** **数值** 压缩比 2.834倍 编码开销 每字节4.31纳秒,约232 MB/s,每次填充时支付一次 解码开销 每字节1.56纳秒,约641 MB/s,每次提供服务时支付 编码的每字节开销更高,但资源被提供服务的频率远高于被填充的频率。 通过改变资源的表示形式,现有硬件可以存储更多的客户内容。 磁盘上的字节越少,每台服务器可以保留的对象就越多。这提高了缓存密度,减少了因未压缩表示占用不必要空间而导致有用内容被驱逐的可能性。 这种更小的表示形式也有助于资源通过分层缓存移动,因为它减少了Cloudflare数据中心之间传输的数据量,使骨干网使用更高效。 ## 一次性支付压缩成本 压缩从来不是免费的。编码和解码都使用CPU,因此重要的问题是节省的字节是否值得为此付出处理成本。 在zstd级别3(通常是速度和压缩大小输出的默认平衡点)下,我们的模型在测试的流量和复用假设下,将额外CPU开销控制在几个百分点以内。 我们最初考虑将转码限制为热门内容,因为热门资源复用更多,但这没有帮助。每次提供资源时都会发生解码,因此将功能限制为最热门的内容,虽然减少了存储节省,但并未同比例减少CPU开销。 更简单的策略表现更好。转码所有大于或等于4 kibibytes(KiB)的符合条件的可压缩文本,几乎捕获了所有测量到的存储效益,同时仍在CPU预算范围内。 ## 缓存转码如何工作 在缓存未命中时,我们基于Pingora的代理**使用zstd对响应体进行编码**,然后再写入磁盘。缓存元数据会记录存储的表示形式是压缩的,并保留原始内容长度。在响应离开代理之前,响应体被**解码回其原始的身份表示**。 在缓存命中时,存储的zstd对象从磁盘读取并解码。通过分层缓存,压缩后的表示形式从上层以压缩形式传输到下层。解码仅在面向客户端的一跳发生。 在完全缓存未命中时,上层从源站获取身份字节。这些字节被编码一次,存储为zstd,并以压缩形式传输到下层。下层也存储zstd表示形式,然后在请求路径中为其解码。 unnamed (77).png 如果下层未命中但上层已有该对象,则不涉及源站。压缩对象直接在缓存层之间移动。它在线路中和磁盘上保持压缩状态,然后在下层解码一次。 如果下层已有该对象,则不需要网络传输或编码。下层从磁盘读取zstd字节,解码它们,并将原始资源传递出去。 存储编码标记防止对象被编码超过一次。从另一个层接收对象的缓存层可以看到它已经使用zstd存储,并以该形式保留它。 ## 为何我们只转码特定文本 最快的压缩操作是我们不需要执行的那一种。因此,缓存转码使用一系列资格检查来避免不太可能受益的内容。 原型仅在`Content-Encoding`未设置、`Content-Type`是可压缩文本、且响应具有已知的至少4 KiB的`Content-Length`时,才对`200 OK`响应进行转码。切片子请求、使用主动上游压缩的响应、范围请求、预压缩响应、未知长度的主体和二进制内容保持不变。 4 KiB的阈值移除了大量微小请求,同时仅排除了约1%原本符合条件的字节。降低此阈值会增加每个对象的开销,却无法节省更多存储空间。 阈值和zstd级别都是参数,而非永久限制。我们从zstd级别3和4 KiB最小值开始,因为它们为我们提供了一种保守的方式来衡量该架构。了解了初始CPU预算后,我们可以测试更高的压缩级别是否能显著提高压缩比,以证明其额外成本是合理的。 ## 在超过一百万个请求中进行测试 我们在一个受控的测试区域上运行了原型,并关联了每个请求的日志、Prometheus指标和Jaeger追踪。 正确性测试涵盖了缓存未命中、缓存命中、单跳填充、分层缓存填充等多种情况。我们改变缓存键以使每个请求遵循特定路径,并使用追踪来确认编码和解码发生的位置。 一个性能测试在10台缓存服务器上发送了超过一百万个请求。一半测试在禁用分层缓存的情况下运行,另一半在启用的情况下运行。这使我们能够分别衡量本地缓存行为和缓存层之间的传输行为。 两个资源分别约为195 KiB和272 KiB,两者均被压缩了大约2.8倍。这是一个故意设计为可压缩的测试集。它为我们验证架构提供了清晰的信号,但并不代表互联网上的每个文本对象。在将测量到的压缩比视为整个集群的常数之前,需要更广泛的测试集。 ## 压缩一次,受益多次 这个实验向我们表明,我们仍然可以在整个缓存服务中部署显著的效率提升,从而惠及所有客户。我们为缓存转码所构建的方案表明,在我们测试的条件下,这种权衡是有利的。该架构保持了内容的完整性,并在CPU预算范围内运行。 对于下一步,我们计划评估更高的zstd级别,测试更广泛的内容类型和对象大小范围,调整资格标准中的不同参数等。未来的工作还可以研究范围请求、预压缩的源站响应,以及直接将压缩对象传递给已支持它的下游组件而不进行解码。 在我的整个实习期间,我有幸与Cloudflare的工程团队一起,为存储和提供全球网络内容的真实基础设施工作。如果你想通过帮助构建更好的互联网来开始你的职业生涯,请探索我们的实习机会(https://www.cloudflare.com/careers/early-talent/)和职位空缺(https://www.cloudflare.com/careers/jobs/)。

相似文章

又节省了100TB RAM

Hacker News Top

Cloudflare通过优化其基于Pingora的负载均衡服务的内存使用,改进了Rust中的pingora-ketama一致性哈希库,从而在全球范围内回收了超过100TB的RAM。

优化1.1.1.1 DNS缓存以节省100TB内存

Hacker News Top

Cloudflare优化了其1.1.1.1 DNS缓存,将内存使用量减少超过50%,节省了100TB内存,并通过优化的Rust数据结构提升了性能。

从局部失配到全局影响:优化高效扩散的缓存复用策略

arXiv cs.AI

本文提出Global-ImpactCache(GCache),一种双层优化框架,通过学习扩散模型的缓存复用策略,将误差加权与最终生成质量对齐,而非依赖局部相似性启发式。它在图像和视频生成任务上实现了显著的加速和质量提升,包括在Wan2.1上实现2.17倍加速且LPIPS更低。