我给网站加了CDN缓存,结果反而更慢了。这是我本该先算的账。

我给网站加了CDN缓存,结果反而更慢了。这是我本该先算的账。

💡 原文英文,约1700词,阅读约需7分钟。
📝

内容提要

在静态网站前添加CDN缓存后,网站反而变慢,慢页面从38个增至75个。原因是缓存未命中时CDN处理更耗时,且爬虫总是冷请求,命中率极低。计算发现需67%命中率才能持平,但实际接近零。建议部署前先计算盈亏平衡命中率,并诚实评估真实命中率。

🔎

延伸解读

缓存未命中的隐性成本

文章实测发现,CDN缓存未命中时,TTFB比直连源站慢约85毫秒。这是因为CDN在回源时需要边转发边存储对象,增加了额外开销。许多开发者误以为未命中只是回到无缓存状态,实际上它比无缓存更慢。因此,在评估CDN收益时,必须将未命中的额外延迟计入成本,而不仅仅是比较命中与未命中的速度。

爬虫请求的冷缓存特性

搜索引擎爬虫通常每个URL只请求一次,且不会重复访问,因此缓存命中率极低。文章中的案例显示,爬虫抓取80个页面时,源站日志记录了82次请求,命中率为0%。这意味着,如果网站流量主要来自爬虫或首次访问用户,CDN缓存可能无法带来性能提升,反而因未命中开销而拖慢响应。

盈亏平衡命中率的计算方法

文章提供了一个简单公式:h > (M - B) / (M - H),其中H为命中耗时,M为未命中耗时,B为无缓存基线耗时。通过该公式,可以计算出使CDN缓存优于无缓存所需的最低命中率。在作者的案例中,需要67%的命中率才能持平,但实际命中率接近零,因此部署前应先计算此值,避免盲目优化。

验证指标应与问题来源一致

作者最初从源站附近测量,得到TTFB改善的结论,但外部爬虫数据却显示慢页面增多。这提醒我们,验证优化效果时,应使用与发现问题时相同的指标和视角。如果问题是由外部爬虫或用户反馈的,就应从他们的地理位置和请求模式进行测量,否则可能得出错误的成功结论。

Q&A

为什么给静态网站加了CDN缓存后反而更慢了?

因为缓存未命中时CDN处理更耗时,且爬虫总是冷请求,命中率极低。作者测量发现,缓存未命中比不缓存慢约85毫秒,而爬虫抓取时命中率为0%,导致整体变慢。

如何计算CDN缓存的盈亏平衡命中率?

公式为 h > (M - B) / (M - H),其中H是缓存命中时间,M是缓存未命中时间,B是不缓存时的基线时间。只有当实际命中率大于该阈值时,缓存才能带来性能提升。

为什么爬虫会导致CDN缓存命中率低?

因为爬虫通常只抓取每个URL一次,不会重复请求,而缓存只有在同一URL被再次请求时才能命中。因此爬虫的请求几乎都是冷请求,命中率接近零。

部署CDN缓存前应该做哪些评估?

首先计算盈亏平衡命中率,然后诚实估计真实命中率(考虑请求量、URL数量、边缘节点分布和部署频率),并从用户和爬虫的实际位置测量性能,而不是从源服务器附近测量。

如何验证CDN缓存是否真正生效?

可以通过检查HTTP响应头中的cf-cache-status字段,如果为HIT则表示缓存命中,为MISS或DYNAMIC则表示未命中。另外,可以通过对比本地构建的页面哈希与线上页面哈希来验证缓存是否更新。

为什么Cloudflare不会仅根据Cache-Control头缓存HTML?

因为Cloudflare默认不缓存扩展名为.html的页面,即使设置了s-maxage等缓存头,也需要显式配置Cache Rule来标记响应为可缓存。作者通过实验验证了这一点。

CDN缓存未命中为什么比不缓存更慢?

因为缓存未命中时,CDN不仅需要代理请求到源服务器,还需要在流式传输过程中存储对象,这增加了额外的工作和时间。作者测量发现,缓存未命中比直接访问源服务器慢约85毫秒。

🏷️

标签

➡️

继续阅读