CDN缓存和TTL优化
简短摘要
CDN-kesh是用户与起源之间的"加速器+屏蔽"。当:1.缓存密钥(缓存密钥)是稳定的,不包含"噪音"。
2.负荷下的TTL政策:'s-maxage'/'max-age'+'stale-wile-revalidate/if-error'。
3.残疾管理:按标签/前缀+"软"purge。
4.包括tiered-cache/origin-shield和negative-cache。
5.有可观察性:按层排序,p95 TTFB,回报比例304。
基本头以及它们的含义
`Cache-Control`:
"max-age=<s>'-浏览器的TTL。
's-maxage=<s>'-CDN/代理的 TTL(重叠'max-age')。
"stale-while-revalidate=<s>"-我们放弃过时,我们并行更新。
"stale-if-error=<s>'-我们给出过时的起源错误。
"immutable"-资源不会改变(适合于固定的推理)。
"ETag"/"Last-Modified"-304的条件,节省字节/CPU起源。
"Vary"是影响缓存密钥的标题列表(使用约束!)。
"Surrogate-Control"是用于CDN的"高级"缓存控制(如果支持)。
"Expires"已过时,但仍由客户考虑。
Cache-Control: public, max-age=31536000, immutable
示例(具有安全过时的半扬声器):
Cache-Control: public, s-maxage=300, max-age=60, stale-while-revalidate=600, stale-if-error=86400
ETag: "a1c3..."
缓存密钥: 设计和规范化
目的是使相同的请求本质上进入同一对象。
URL归一化:寄存器,双斜线,预告片,查询参数顺序。
忽略"噪音":"utm_","fbclid","gclid"和任意裁判标签。
限量版:只有真正重要的标题("接受编码",有时是"接受","接受语言"用于本地化)。
设备类:如果需要,请使用2-3类(移动/desktop/tablet),而不是分支的无限用户代理。
Auth上下文:默认情况下,不要取消私有;使用signed-URLs/cookies-bypass或公共/私人路径分离。
Surrogate-Key: product:123 catalog
Cache-Control: public, s-maxage=300, stale-while-revalidate=600
Vary: Accept-Encoding
跨内容类型的TTL策略
残疾政策
通过URL/Prefix: "把一切都转移到'/static/2025-11-05/'下。"
By Tag/Key:"删除整个'catalog'和'product: 123'。
Soft purge:标记为过时,不要擦除对象-更快地重新填充。
事件驱动程序:CI/CD或管理事件调用webhook"入侵标签"。
建议:将两种策略结合起来:为内容/页面提供+标签支架的路径。
Tiered-cache, origin-shield и prewarm
Tiered-cache:区域CDN层对起源的查询→少。
Origin-shield:一个"盾牌"POP to origin-提高了位置和命中率。
Prewarm (pre-fetch): 在活动/发布之前加热热URL/缓存。
Negative-cache:短暂地5xx/Timeout(30-120 s),以免被暴风雨的后退淹没。
Kesh API: 什么时候可以
只有GET/HEAD和偶数。
关键:路径+基本查询(例如'?category=……&page=……')。
验证:"ETag"/"Last-Modified"和简短的"s-maxage"。
用户过滤器:对客户端/边缘功能进行个性化处理或使用签名请求+"公开"响应。
Cache-Control: public, s-maxage=30, max-age=5, stale-while-revalidate=120, stale-if-error=600
ETag: "feed-v42"
缓存中毒(cache poisoning)保护)
严格的URL/标题归一化;键中参数的白色列表。
修剪可疑标题/重复内容("X-Forwarded-",扩展的"接受")。
限制"Vary"并控制标题的大小/数量。
分域:私有/管理员-在没有缓存的单独名称上。
验证响应:不缓存4xx(静态除外404),不缓存"自定义"页面没有显式策略。
压缩和格式
文本的Brotli(js/css/json),gzip-fallback;预压缩asset是允许的。
图片:支持的webp/avif;使用"Vary: Accept"+衍生产品。
视频/音频的范围请求:CDN缓存钱币。
Content-Negotation:保持低键基数(设备类而不是原始UA)。
可观察性和SLO
关键指标
Hit-ratio (by bytes/requests) на edge/tier/shield.
p50/95/99按区域和类型(静态/APIs)分列的TTFB。
Fill-rate/Origin egress-有多少人离开了起源。
304 rate和平均响应大小。
错误预算:"stale-if-error"/"SWR"发行的一部分;purge频率。
SLO示例
"p95 TTFB"静力学在区域上≤ 120-150毫秒,可加权的API ≤ 200-250毫秒。
Edge hit-ratio静态≥ 90%,半动态≥ 60%。
错误时来自样式分支的响应比例≤ 0。在30天内达到5%。
Config Spargalks
Nginx(在CDN之前或在self-PoP中)
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CDN:512m max_size=100g inactive=7d;
map $args $clean_args {
"~(^ &)(utm_ gclid fbclid) """; # default $ args simplified example;
}
server {
listen 443 ssl http2;
set $cache_key "$scheme$request_method$host$uri?$clean_args $http_accept $http_accept_encoding";
location /static/ {
proxy_cache CDN;
proxy_cache_key $cache_key;
proxy_ignore_headers Set-Cookie;
add_header Cache-Control "public, s-maxage=86400, max-age=3600, stale-while-revalidate=600" always;
proxy_pass https://origin_static;
}
location /api/public/ {
proxy_cache CDN;
proxy_cache_key $cache_key;
proxy_cache_valid 200 30s;
add_header Cache-Control "public, s-maxage=30, max-age=5, stale-while-revalidate=120, stale-if-error=600" always;
proxy_set_header If-None-Match $upstream_http_etag;
proxy_pass https://origin_api;
}
}
Envoy (SWR+negative-cache,概念)
yaml http_filters:
- name: envoy. filters. http. cache typed_config:
"@type": type. googleapis. com/envoy. extensions. filters. http. cache. v3. CacheConfig typed_config:
"@type": type. googleapis. com/envoy. extensions. cache. simple_http_cache. v3. SimpleHttpCacheConfig
Cache-Control/Surrogate-Control Header Cache Policies
We cache 5xx errors briefly via route/retry policy + local_rate_limit
用于"快速"assets的头部
Cache-Control: public, max-age=31536000, immutable
ETag: "hash"
Content-Encoding: br
半扬声器的头部(目录)
Cache-Control: public, s-maxage=600, max-age=120, stale-while-revalidate=1800, stale-if-error=86400
Vary: Accept-Encoding, Accept
FinOps: 缓存如何省钱
Egress起源↓,CPU/DB负载较少→基础架构成本较低。
有偿后端(search/index/images)的查询较少。
目标指标:$/减少p95和$/egress减少1 GB-跟踪后期效果。
iGaming/fintech的细节
提供商/代理目录:转售路径+年度TTL。
赛事/锦标赛登陆:10-30分钟的1-5分钟"s-maxage"+"SWR";升级时的标签购买。
Live Page(系数/表):部分JSON块缓存,短TTL (5-30 s),对于个人块-客户端渲染。
PSP/支付端口:不打包,严格的"无商店";仅缓存参考书(BIN表、状态)。
Antibot:静态/GET缓存,可疑的ASN的"灰色"路线;不要在嘈杂的标题上允许"Vary"。
实施支票
- 描述了缓存密钥:URL归一化、允许查询列表、"Vary"仅按所需设置。
- 公共道路/私人道路是分开的;私有-"no-store"和旁路CDN。
- 按内容类型介绍了TTL梯子;设置为"SWR/if-error"。
- 配置了tiered-cache+origin-shield;包括negative-cache 5xx(短)。
- 有tag/URL purge, soft purge;与CI/CD集成。
- 启用了压缩(br/gzip)、Web图像格式和范围响应。
- 度量标准:按层排列的hit-ratio,p95 TTFB,304 rate,origin egress;失误。
- 花花公子:在峰值前加热缓存,紧急冲浪,降解起源。
典型错误
大型TTL的无凡尔赛assets在用户中→"扎根"的帮派。
过度的"Vary"(通过"User-Agent",所有标题)→基数爆炸和低命中率。
4 x/401/403/私有内容缓存。
缺少negative-cache →降级起源请求的雪崩。
没有标记陷阱→质量点陷阱和re-fill的"风暴"。
缓存密钥包括"嘈杂"UTM/ref参数。
对于静电而言,TTL太短,→对CDN和起源施加额外的负载。
迷你花花公子
1)在事件发生前预热缓存
1.按逻辑收集前N URL → 2)按区域分列并行预览(rate-limited) → 3)检查最高↑和p95 ↓。
2)紧急软冲刺阴道学家
1.发送"PURGE"/tag-c → lear 2) CDN给出样式,背景拉起新鲜的→ 3)检查起源上没有尖峰。
3)原产地拒绝
1. "stale-if-error"指定X时钟 2)在Edge 3上打开"techrobs"横幅)通过恢复-目标扭曲。
结果
强大的CDN策略=正确的缓存密钥+具有SWR/if-error+受控残疾+tiered/shield+可观察性的有意义的TTL。在heders和IaC中记录策略,测量热值和p95,计划在峰值下加热-用户总是会得到快速响应,即使是最热的时刻,起源也会保持活着。