4.2 CDN 加速:缓存与刷新策略

场景:跨地域用户下载像树懒

团队在总部,外地同事下载网盘文件总觉得慢,尤其晚上高峰。根源是 COS 桶只有一个地域,所有请求都回源到那个机房。对本地用户快,对远方用户就是远程拉取。视频预览尤其明显,外地打开视频要缓冲半天。

CDN 的作用是把内容缓存到各地的边缘节点,用户就近取。对我们这种流量集中在下载与预览的场景,CDN 是几乎无脑的选择——直到账单提醒你这个无脑也有代价。

方案:计费与缓存策略

CDN 的计费方式先要选对,流量包还是带宽峰值:

计费方式 适用流量特征 我们的选择
按流量 波动大,偶发高峰 采用
按带宽峰值 平稳持续大流量 备选

我们的流量是脉冲式的(一批素材传完一群人抢着下),按流量买包更划算。月均 200GB 量级,流量包费用约每月 180 元,对比直接经后端公网的固定带宽费用,省了九成。

缓存策略决定命中率,命中率决定回源量,回源量决定账单:

资源类型 缓存时长 跟随源站
缩略图与转码产物 30 天 否,内容不变
原图与原始文件 不缓存或短 是
公共素材 1 年 否

预览与缩略图类内容指纹固定,长缓存无风险;原始文件带签名参数,URL 每次不同,缓存意义不大。

配置:刷新与预热

文件更新时主动刷新 CDN,否则用户看到旧版本。刷新分目录与链接两种粒度,接口调用即可:

// 文件更新后刷新对应 URL 的缓存
cds.FlushURLs(ctx, []string{
    cosURL(key), cosURL(key) + "?imageMogr2/thumbnail/200x",
})

预热是相反方向:主动把内容推到边缘节点。我们对大批公开素材做预热,首次访问也不慢。日常更新用刷新,批量上线用预热。

踩坑:CDN 的四个坑

第一个坑,CNAME 配错。域名接入 CDN 后要修改解析,一步走错全站打不开。上线前先在测试域名上走完整流程,别拿生产域名练手。遵守古老的仪式感:改解析前先截图存证据。

第二个坑,命中率低。最初我们把带签名参数的私有链接也走 CDN,每个链接都不同命中率几乎为零,全是回源流量。后来只让公开素材与固定 URL 的资源走 CDN,私有走 COS 直连,命中率立刻拉到 90% 以上。

第三个坑,缓存与更新不同步。源文件改了但缓存没刷,用户看到的还是旧的,投诉到产品那里就是事故。核心文件我们做了更新后自动刷 CDN 的联动,配置在 SCF 事件里,重要文件绝不能靠手工刷。

第四个坑,盗刷防治。CDN 一旦把内容公开,第三方站点可以白嫖你的流量。必须配合防盗链,Referer 校验是基础,签名鉴权是加强,细节在 4.3 防盗链一节。

CDN 接入的标准动作是四步:控制台添加加速域名、拿到 CNAME、去 DNS 改解析、等全网生效。前三年我们反复在第三步上栽跟头,DNS 那边一旦配错,排查链路能从 CDN 扯到域名商。后来形成规矩:任何解析变更,改之前截图,改之后用解析工具连验三遍。

HTTPS 证书一开始想省事用 CDN 提供的免费证书,到期要手动续。有次续期忘了,用户浏览器弹大红警告,客服电话半小时炸了。之后全部改用托管证书自动续期,能自动的事情绝不用人脑记。

命中率是 CDN 的生命线,我们把它配进监控大屏。健康值在 90% 以上,低于 75% 就告警。有次命中率突然掉到 40%,查下来是客户端改了 URL 拼接规则导致参数变化,缓存全失效。监控比用户先发现问题,这就是它的价值。

流量包购买时机有学问。月初看上月用量决定档期,遇到素材集中上传的月份提前囤包。买超了浪费,买少了按弹性计费单价翻倍。我们维护了一张用量表格,三个月移动平均做采购基线,运行半年后浪费与缺口都控制住了。

预热主要服务两种场景:一是大批公开素材上线,二是营销活动预热物料。预热接口有配额,几万条 URL 要分批送。我们有一次把预热任务全挤在同一时刻,接口限流拒了一大半,只能写重试队列慢慢吞。

视频预览对 CDN 依赖最重。转码后的多分辨率版本走 CDN,用户拖进度条基本秒开。原始文件不走 CDN 只走 COS,原因是带签名的 URL 缓存不住,硬上只会既费钱又无效。

海外访问是我们后补的功课。早期只在大陆节点,海外同事下载速度惨不忍睹。开启全球加速后回源策略要调,默认回源到最近地域会绕远路,我们指定回源到桶所在地域,延迟反而更稳定。

节点故障难避免。某次华东节点抖动,部分用户下载卡顿,CDN 自动切换在其他节点完成,但耗时上升明显。后来我们给核心域名配了容灾切换开关,极端情况能手动切回 COS 直连,保下限不保上限。

回源压力要控制。命中率突然下降时回源请求会涌向 COS,可能把桶的限频打满。我们给回源并发设了上限,同时监控回源速率。CDN 是加速器,但它把流量放大器也一起带来了,两面性时刻记着。

大文件下载的体验优化在 CDN 这一层做最划算。分片回源、断点续传都由边缘节点承担,用户感知就是快。对比之前所有压力都在后端服务器上,现在机房安静了,账单也没涨多少,这是架构升级该有的样子。

每月账单复盘是固定动作。流量、回源、请求数分开看,找出异常增长项。有个月请求数量翻倍但流量没变,查出来是大量 304 空响应,属于正常行为但值得记录。账单里的每个数字都该有解释。

移动端弱网是另一个世界。地铁里下载视频,CDN 边缘节点的就近优势非常明显。我们还根据用户反馈调低了移动端视频默认码率,让缓冲先消失,体验比清晰度重要。

CDN 与 COS 之间的链路也要养护。回源走的是内网还是公网、是否走了专线,这些在开通时就要确认。我们有次排查延迟问题,绕了半天发现是回源走了公网绕行,改内网后延迟降了一半。开通时省的事,排查时加倍还。

状态码监控是 CDN 健康度的晴雨表。5xx 突增多半是源站问题,4xx 突增要怀疑鉴权或配置变更。每个告警阈值都要根据历史水位标定,拍脑袋设的阈值不是告警是噪音。

大促或素材集中投放前我们做容量预演。预估峰值带宽、提前备好流量包、预热物料,三件套缺一不可。经历过一次准备不足导致的回源雪崩,全组对预演这件事再无异议。

CDN 的用量数据接进了成本看板。每日流量、回源比、缓存命中率、费用估算实时可见,配合 5.3 的监控告警形成经营闭环。账单出来再心疼是马后炮,看着曲线做决策才是经营。

CDN 域名分租是后来的优化。多个业务线共用一个 CDN 域名时,某条业务的缓存策略误伤全场。拆成按业务的域名后,各自独立配缓存与防盗链,故障域天然隔离。共用一时爽,拆分保平安。

缓存键的设计也有坑。带排序参数的列表类资源缓存命中率极低,每个排序组合都是新键。后来把高频排序固定、低频排序不缓存,命中率回到九成。缓存是万能的,但不是所有地址都该缓存。

新旧文件版本的缓存隔离靠地址而非刷新。新上传自动带版本号,老地址自然失效,刷新接口只处理兜底场景。能用命名解决的事情不要用运维解决,这个原则在缓存设计里屡试不爽。

我们踩过一次回源熔断。有次桶的限频被打到,CDN 回源全部 5xx,前端却只看到慢。加了对回源状态码的单独告警后,这类故障十分钟内就能定位。监控颗粒度决定故障定位速度。

顺带说一句工具链。CDN 的日常操作我们全部走命令行与脚本,刷新、预热、查状态码都封装成内部工具。控制台点点适应不了高频运维,把重复动作沉淀成工具是运维的基本修养。

最后强调一次成本视角。CDN 是本篇里唯一持续花钱的模块,月账单从一百到一万都可能。把用量数据钉在看板上,把预算红线配进告警里,让加速器装上仪表盘再上路。

补充一个冷知识:CDN 的缓存命中率与后端省的钱直接挂钩。我们做过测算,命中率每提升五个百分点,月流量费下降约百分之四。监控大屏上那根曲线,其实是钱的形状。

这一节的所有经验都来自两年实操,不含任何官方文档的复述。CDN 文档很全,但文档不会告诉你凌晨三点排查解析记录的感觉,而这份笔记会。

再啰嗦一句选型心得:CDN 厂商切换成本很高,域名、规则、证书都要迁移,选型时多花两周值得。我们最终选择标准只有两条:节点覆盖与工单响应速度,功能反倒在其次。

缓存预热做了分级。核心素材全量预热,普通素材按热度预测预热前百分之二十。分级后预热配额再没超限,冷启动慢的投诉也消失在数据里。

流量包的采购决策每月初过一次会。上月用量、本月预测、活动日历三张牌摆在一起,买多买少当场拍板。开销管理形成例会习惯了,意外账单就绝了迹。

全球加速的回源策略我们调过好几次。默认回源到最近节点在跨国场景反而绕路,固定回源到桶所在地域后,海外同事的下载耗时稳稳降下来。经验是默认值不一定最优,得按业务测。

缓存命中率掉了的那次事故教会我们把客户端版本与缓存策略绑定监控。发版当天但凡命中率曲线抖动,值班群立刻警觉,发现速度比客户投诉快了整整一天。

小结

CDN 是网盘的速度引擎,用得对省时省钱,用不对就是费钱机器。记住三句话:公开资源才上 CDN、指纹变则缓存变、刷新自动化。把这三条做扎实,CDN 就是你的超级加速器。

延伸阅读