想象一下:你开了一家网店,商品全都堆在城郊的中央仓库。顾客从城西下单,快递员却要横穿整个城市跑到城东取货,再折返送回去——来回三小时,顾客等得花儿都谢了。怎么办?你在东南西北各租一间前置仓,把最热门的商品提前备好。顾客下单,离他最近的仓库直接出货,几分钟送达;本地缺货,才派人去中央仓库调货。这套“前置仓+中央仓”的体系,成就了现实中的快递网络,也正是 CDN(内容分发网络)的核心思想。 CDN 把“内容”这种数字货物,从源站(中央仓库)复制到遍布各地的边缘节点(前置仓)。当用户请求视频、图片、网页时,调度中心(DNS)会把他引导到最近、最不拥堵的边缘节点直接取货——命中缓存就秒回,不命中才回源站拉取。你将在快递网络的比喻中,拆解 CDN 的三大引擎:内容路由、缓存策略、负载均衡,并延伸出一致性哈希与回源容灾等面试必考点,最终在面试中自信画出 CDN 系统设计蓝图。

岗位关联

职业价值:CDN 是系统设计面试的高频考题,掌握它的分层架构与缓存原理,能体现你从单机思维跃迁到分布式架构的工程能力,是后端与基础架构岗位的加分项。

目录
  1. 可视化演示
  2. CDN基础概念
  3. 边缘节点架构
  4. 内容路由机制
  5. 缓存策略设计
  6. 一致性哈希
  7. 负载均衡设计
  8. 回源与容灾
  9. 面试设计方案
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示CDN设计的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

CDN设计:CDN架 CDN架构原理与边缘节点模型 内容路由与DNS调度机制 核心机制可视化 CDN设计整体架构与关键组件

CDN基础概念

还记得那个“前置仓+中央仓”的快递网络吗?我们把它翻译成技术语言:前置仓叫边缘节点,中央仓叫源站,货车司机叫内容路由,快递小哥的备货手册叫缓存。CDN 的官方定义是——通过在全球部署边缘节点,将内容缓存到离用户更近的地方,从而降低访问延迟、减轻源站压力的分布式网络。

一个完整的 CDN 由三个组件协作:源站(内容最终来源)、边缘节点(内容缓存层)、调度中心(DNS/GSLB,决定用户去哪个节点)。用户访问网页时,浏览器先向 DNS 询问“这个域名该连哪台服务器”,调度中心根据用户地理位置、节点负载和网络状况,返回一个最优边缘节点的 IP。随后用户直接与该节点建立连接,拿到缓存的图片、视频或 HTML 页面。

要量化 CDN 的收益,先看清一次 HTTP 请求的延迟构成。用户的端到端耗时可分解为四个阶段,CDN 优化的正是中间两个:

CDN 的“前置仓思维”本质上是用空间换时间——用分布式存储的成本,换取用户体验的直线提升。在面试中,你可以把这段话作为开场白:CDN 解决的问题只有一个——让内容离用户更近,让源站活得更轻松。

Ttotal=Tdns+Tconn+Tttfb+Tdownload\displaystyle T_{total} = T_{dns} + T_{conn} + T_{ttfb} + T_{download}
  1. DNS 解析时间浏览器把域名翻译成 IP 所需的时间。CDN 调度器在这里介入,返回最优节点 IP,从而改变后续三条链路的路由方向。
    TdnsT_{dns}
  2. 连接建立时间TCP 三次握手 + TLS 握手的往返延迟。用户与边缘节点距离越近,握手次数(RTT)就越少,连接建立也就越快。
    TconnT_{conn}
  3. 首字节时间请求到达服务器后,到返回首个字节的等待时间。边缘节点命中缓存时,这段等待时间几乎为零,因为无需穿透到源站执行复杂计算。
    TttfbT_{ttfb}
  4. 下载传输时间主体内容(尤其是大文件)从服务器传到浏览器的耗时。CDN 不仅离用户更近,还常用更优的传输协议与带宽,让下载速度更快。
    TdownloadT_{download}

边缘节点架构

前置仓不是随便租的——得考虑地段、面积和热销品类。CDN 的边缘节点架构也是同样的道理:节点按层级分布,内容按热度投放,容量按流量规划。

CDN 节点通常分三层。核心层(国家级节点)存放全量内容,处理回源和低频数据;区域层(省级节点)缓存区域内高频内容;边缘层(城市节点)最贴近用户,承接 80% 以上的热内容请求。用户在边缘层就能命中,自然不需要层层向上穿透。这种分层架构就像快递网络:前置仓解决 90% 的订单,剩下的疑难件才送回中央仓。

面试中常问“一个 CDN 需要多少个边缘节点”。这道题考察的是容量规划能力。假设总 QPS 为 Q,每个节点能承受的上限为 Q_cap,再考虑缓存未命中率 p_miss(需要回源的比例),可以估算节点数下限:

边缘节点的架构设计还得分清场景:静态资源(图片、CSS、视频)直接缓存到节点磁盘,命中即返回;动态内容(接口、个性化页面)则通过优化链路(如专线回源、连接复用)来降低延迟。面试时,说到“边缘节点”别只想到缓存,还要点出它同时具备 路由、负载均衡、安全防护 三层职能——它在快递网络里既是备货仓库,也是区域调度站。

N=⌈Q×pmissQcap⌉\displaystyle N = \left\lceil \frac{Q \times p_{miss}}{Q_{cap}} \right\rceil
  1. 总请求量Q 是全网每秒到达 CDN 的请求总数。比如 1 亿日活的 App,若人均每天发 10 个请求,则 Q ≈ 1.16 万 QPS。
    QQ
  2. 缓存未命中率p_miss 表示请求中需要穿透到源站的比例。它受缓存策略和内容热度分布影响,通常在 5%~20% 之间。
    pmissp_{miss}
  3. 单节点承载上限Q_cap 是单个边缘节点每秒能处理的请求数,取决于机器配置、内存缓存和带宽,经验值约 5000~20000 QPS。
    QcapQ_{cap}
  4. 向上取整节点数不能出现“半个节点”,用向上取整保证容量大于需求,留出余量应对流量突刺。
    ⌈⋅⌉\lceil \cdot \rceil

内容路由机制

前置仓建好了,顾客怎么知道去哪个仓库取货?总得有个“导航系统”。CDN 的内容路由就是这套导航系统,而它的核心枢纽是 DNS 调度。

当用户敲下网址,浏览器发起的第一次 DNS 解析请求会到达 CDN 运营的权威 DNS 服务器。此时调度器执行“就近原则”:结合用户的来源 IP(可推算地理位置)、各边缘节点的实时负载和网络健康状态,选出一个综合得分最高的节点 IP 返回。用户拿到 IP 后直接连接该节点——就像导航软件根据实时路况,把你导到不堵车的最近前置仓。

在面试中,你可以这样描述评分模型:调度器给每个候选节点打分,得分最低者胜出。其中 G_i 表示地理距离得分,R_i 表示网络链路质量(RTT)得分,L_i 表示节点当前负载得分,三项加权求和:

内容路由的最终效果,是把每次请求“导航”到最合适的边缘节点。面试官如果追问“DNS 调度有什么缺点”,你可以回答:DNS 缓存可能让用户拿到过期 IP、跨运营商调度不精准——因此大型 CDN 还会辅以 Anycast(任一播)和 HTTP 重定向做二次调度,让导航系统更聪明。

scorei=α⋅Gi+β⋅Ri+γ⋅Li\displaystyle score_i = \alpha \cdot G_i + \beta \cdot R_i + \gamma \cdot L_i
  1. 地理距离分G_i 越小代表节点离用户越近。调度器通过 IP 库或延迟探测获取用户位置,淘汰“隔了半个地球”的候选者。
    GiG_i
  2. 链路质量分R_i 由实时 RTT(往返时间)决定。链路好的节点得分低,网络抖动或断连的节点会被抬高分数,自然被淘汰。
    RiR_i
  3. 负载分L_i 反映节点的 CPU、带宽和连接数占用率。负载过高时节点分数升高,流量会优先流向空闲节点,实现隐式均衡。
    LiL_i
  4. 权重系数α、β、γ 是三个维度的影响力权重。比如视频网站更看重带宽(γ 加大),游戏平台更看重延迟(β 加大)。调度器通过调权来适配不同业务。
    α,β,γ\alpha, \beta, \gamma

缓存策略设计

前置仓的库存管理是门学问:备货太多,过期浪费;备货太少,顾客扑空。CDN 的缓存策略同样在“新鲜度”和“命中率”之间做权衡,核心工具就是 TTL(有效期)。

每个缓存内容都带一个“保质期”—TTL。在 TTL 内,边缘节点直接返回缓存副本;TTL 过期后,节点重新向源站请求最新版本。TTL 设置得太短,回源频繁,源站压力大;太长,内容更新不及时,用户看到旧数据。面试中可以说:静态资源(如版本号命名的 JS/CSS)可设长 TTL 甚至永久缓存;高频变化的接口数据则设 30~60 秒的短 TTL。

有趣的是,缓存命中率与 TTL 之间存在指数关系。如果内容访问频率随时间指数衰减(衰减系数为 λ),则在有效期 T 内的累计命中概率为:

TTL 解决了“什么时候过期”,淘汰算法解决“缓存满了装什么”。最常用的是 LRU(最近最少使用):淘汰最久没被访问的内容——就像前置仓把滞销品退给中央仓,给爆款腾地方。当命中的内容被提前预取到边缘节点、失效的内容主动更新时,这套缓存体系就从“被动缓存”进化成了“主动运营”:不仅用户来取货时能拿到,还能预测需求提前备货。

Hcache=1−e−λ⋅TTL\displaystyle H_{cache} = 1 - e^{-\lambda \cdot TTL}
  1. 访问衰减系数λ 描述内容热度衰减的速度。热搜新闻的 λ 很大(几小时就冷却),经典文章 λ 很小(长期有人看)。λ 越大,TTL 就要越短以保新鲜。
    λ\lambda
  2. 内容有效期TTL 是缓存副本可信任的时间窗口。窗口内命中不用回源,窗口外必须回源刷新。
    TTLTTL
  3. 积累命中概率1 − e^(−λ·TTL) 表示在一个 TTL 周期内,该内容至少被访问一次的概率。TTL 越长、λ 越大,命中概率越高——但过度延长 TTL 会牺牲新鲜度,面试时要说出这个取舍。
    1−e−λ⋅TTL1 - e^{-\lambda \cdot TTL}

一致性哈希

快递网络里有个隐藏需求:同一个顾客的件最好由同一个仓库负责,否则他上午在 A 仓取件,下午又去 B 仓取件,体验割裂。CDN 的缓存路由同样希望“同一个 key 永远落在同一个节点上”—这就是一致性哈希的用武之地。

一致性哈希把节点和 key 都映射到一个 0~2^32−1 的哈希环上。请求 key 沿着环顺时针找第一个节点,那个节点就负责处理该 key。这个“顺时针碰见谁就是谁”的规则,保证了确定性:同一个 key 永远找到同一个节点。若节点数量变化(新增或下线一个仓库),只有环上部分 key 被重新映射,受影响的只是相邻区段——这正是它优于传统取模哈希的关键。

为了让节点在环上分布更均匀,引入虚拟节点技术:每个物理节点在环上复制 K 个虚拟位置(相当于一个仓库开 K 个窗口),每个虚拟位置由原始节点 ID 加盐后哈希得到:

面试时,一致性哈希的故事可以这样讲:取模哈希在节点变化时需要重新映射全部 key(所有仓库换货架),一致性哈希只影响环上的一小段(只换一个货架),配合虚拟节点又解决了负载不均,因此在缓存系统和分布式存储中是标配方案。

vi=hash(nodei  +  k⋅salt)(k=0,1,…,K−1)\displaystyle v_i = \text{hash}(node_i \;+\; k \cdot salt) \quad (k = 0, 1, \dots, K-1)
  1. 节点哈希hash(node_i + k·salt) 生成第 i 个节点的第 k 个虚拟位置。k 遍历 0 到 K−1,让每个物理节点在环上拥有 K 个“分身”。
    hash(nodei+k⋅salt)\text{hash}(node_i + k \cdot salt)
  2. 加盐扰动salt 是固定字符串(如 "vnode"),保证不同节点的哈希值不同,避免哈希碰撞导致的分布不均。
    k⋅saltk \cdot salt
  3. 虚拟节点总数K 个虚拟位置将环切分成更细的区间,使各节点管辖的范围趋近均匀,缓解“数据倾斜”——即某些节点管太多、少数节点管太少的问题。
    k=0,1,…,K−1k = 0, 1, \dots, K-1

负载均衡设计

前置仓多了,顾客蜂拥到某一家,其他家空转——这是浪费;某家仓库宕机,重试请求全都超时——这是灾难。负载均衡就是 CDN 的流量调度中枢,它分为两个层面:全局和局部。

全局负载均衡(GSLB)在集群层面做调度:当 DNS 解析时,GSLB 综合地域、网络、负载给用户选“哪个区域的节点”。局部负载均衡(SLB)在节点内部做分发:请求到达某个边缘节点集群后,SLB 把它转发给某台具体机器。GSLB 是“选仓库”,SLB 是“选仓库里的窗口”。

负载均衡的算法很多,加权轮询是经典方案。假设集群有 n 台机器,权重 w_i 表示第 i 台机器的处理能力,那么请求分配到第 i 台的概率是权重占比:

负载均衡的面试要点是“分层”。一个问题抛出来:DNS 返回的 IP 是随机的吗?不是。GSLB 先过滤掉不健康和过载的节点,SLB 再在集群内精细分流。两层配合,既保证了全局调度的最优性,又保证了局部流量的均匀性——就像导航先选城市,进城后再按路况选街道。

Pi=wi∑j=1nwj\displaystyle P_i = \frac{w_i}{\sum_{j=1}^{n} w_j}
  1. 单机权重w_i 根据机器配置和负载动态调整。新机器权重低、老机器权重高,避免请求洪峰集中打爆一台。
    wiw_i
  2. 总权重所有机器权重之和作为分母,将概率归一化。请求按权重比例分发,能力强的机器多接单。
    ∑j=1nwj\sum_{j=1}^{n} w_j
  3. 选择概率P_i 就是第 i 台机器被选中的概率。配合健康检查——SLB 定期探测机器存活状态,异常机器自动摘除、恢复后自动加回——整个集群就有了自愈能力。

回源与容灾

前置仓缺货怎么办?答案是“回源”—去中央仓调货。但如果中央仓本身也断了,整个网络就瘫痪了。CDN 的容灾设计,就是给“调货”加上保险丝和备用通道。

回源机制解决“边缘节点没有内容时从哪里取”的问题。常规流程是:用户请求到达边缘节点,缓存未命中 → 节点向源站发起回源请求 → 拿到内容后存进缓存 → 返回给用户。回源可以走直连专线(质量高但成本高),也可以走公网(成本低但慢)。为了防止“缓存雪崩”(大量内容同时过期导致回源风暴),实际系统会引入回源限流:同一时刻只允许一定比例的请求穿透到源站,其他请求耐心等待或返回降级内容。

容灾设计关注“源站挂了怎么办”。常用的手段是多源站故障转移:配置主备两个源站,主源站连续超时或返回错误时,自动把回源流量切换至备用源站。同时配合超时重试策略——回源请求设有超时时间(如 3 秒),超时后重试下一台源站,最多重试 2 次,避免无限等待拖垮边缘节点。

多副本容灾的可用性可以用概率模型解释。假设系统由 n 个独立组件构成,每个组件可用性为 A_i,只要有一台存活,整体就可用:

回源与容灾是面试中的“保险题”。把回源流程、重试上限、故障转移、降级策略讲清楚,面试官就能判断你是否考虑过生产环境的极端情况——前置仓不仅要有货,还要有应急预案。

Atotal=1−∏i=1n(1−Ai)\displaystyle A_{total} = 1 - \prod_{i=1}^{n} (1 - A_i)
  1. 组件不可用率1 − A_i 是单个组件(如一台源站、一条专线)在单位时间内不可用的概率。
    1−Ai1 - A_i
  2. 全部不可用∏ 表示所有组件同时不可用的概率。组件越多、可靠性越高,但前提是组件相互独立、故障不关联。
    ∏i=1n(1−Ai)\prod_{i=1}^{n} (1 - A_i)
  3. 整体可用性用 1 减去“全部不可用”的概率,就得到至少一个组件存活的概率。比如两个可用性 99% 的源站互相备份,整体可用性提升到 99.99%。
    1−∏i=1n(1−Ai)1 - \prod_{i=1}^{n} (1 - A_i)

面试设计方案

现在把你的快递网络从纸上落到面试官面前。系统设计面试的 CDN 题目,本质是考察你能否有条理地完成一次架构设计。遵循“先需求、后架构、再优化”的节奏。

第一步:明确需求。 面试官没给的数字,先自己设定。问清楚:业务类型是视频点播还是 API 加速?目标用户在地域上如何分布?预估 QPS 和带宽是多少?假设日活 1000 万用户,每人每天平均 10 次内容请求,得出总 QPS 约 1.16 万,高峰期翻 3 倍约 3.5 万。单视频请求的平均响应体量按 1MB 估算,带宽需求就是 3.5 万 × 1MB ≈ 280 Gbps。

第二步:画架构。 画出五层结构:用户层 → DNS/GSLB 调度层 → 边缘节点层 → 回源链路层 → 源站层。每层说清职责:调度层做就近路由,边缘层做 TTL 缓存 + LRU 淘汰,回源层做超时重试和限流,源站层做多机房热备。

第三步:算容量与扩展性。 用边缘节点数估算公式,结合百 TB 级别的总缓存容量需求,给出节点规模。再谈数据倾斜——用一致性哈希 + 虚拟节点解决;节点爆炸——用 GSLB 做分区域水平扩展;热点文件——用 LFU 和预取机制兜底。这一套组合拳下来,架构的扩展性就有血有肉了。

最后留个“加分彩蛋”:主动提出监控指标。命中率、回源带宽、边缘节点健康度、P95 延迟——用数据驱动调优。面试官想听的,不是完美的架构,而是一个懂得用方案解决问题的工程师——就像一个好的快递网络,不是仓库越多越好,而是每个环节都恰到好处。

---

QPSedge=U×RreqNedge×η\displaystyle QPS_{edge} = \frac{U \times R_{req}}{N_{edge} \times \eta}
  1. 日活跃用户数U 是业务每天活跃的独立用户数,作为流量估算的起点。千万日活与百万日活的架构设计完全不同。
    UU
  2. 人均请求数R_req 是每个日活用户每天发起的平均内容请求次数。可以通过业务埋点估出,比如视频 App 大约 10~50 次/天。
    RreqR_{req}
  3. 边缘节点数与效率系数N_edge 是部署的节点数量,η 是容量利用效率(一般取 0.3~0.5,因为要留峰值余量)。总流量除以节点数和效率,就得到单节点的 QPS 要求,再与 Q_cap 对照验证。
    Nedge×ηN_{edge} \times \eta

AI 应用场景

视频点播平台加速

阶段:架构设计 / 性能优化

解决的问题:视频点播业务最怕“卡”和“慢”。传统模式下所有视频都从源站分发,带宽成本高且用户跨地域访问延迟大。CDN 将热门影片提前分发到各区域边缘节点,用户从就近节点拉流,首帧时间从 3 秒降到 500 毫秒,源站带宽压力下降 90%。

具体案例:某长视频平台上线新剧,瞬时峰值 QPS 突破 10 万。通过 CDN 边缘节点 + 预取策略,将热搜剧集提前推送到全国节点,命中率从 60% 提升至 95%,用户投诉显著下降。

电商大促动态内容加速

阶段:系统设计 / 容量规划

解决的问题:电商大促的秒杀接口是动态请求,缓存困难且源站压力巨大。CDN 通过“边缘计算 + 动态加速”能力,在边缘节点完成参数校验、限流和结果缓存,将回源请求量削减 70%,同时用专线优化动态链路,保障大促期间接口 P99 延迟小于 100ms。

具体案例:某电商平台双十一期间,使用 CDN 动态加速 + 边缘脚本过滤无效刷单请求,源站 QPS 峰值从 200 万降到 60 万,数据库不再被打爆,订单成功率保持在 99.9% 以上。

Python 演示

python89 行
"""简化版CDN模拟器:边缘节点缓存 + 一致性哈希路由 + 回源机制"""import hashlibfrom collections import OrderedDictfrom typing import Dict, List, Tuple  class EdgeNode:    """边缘节点:带LRU缓存的迷你服务器"""    def __init__(self, node_id: str, capacity: int = 100):        self.node_id = node_id        self.capacity = capacity        self.cache: Dict[str, str] = OrderedDict()        self.hit_count = 0        self.miss_count = 0     def get(self, key: str) -> str:        if key in self.cache:            self.hit_count += 1            self.cache.move_to_end(key)            return self.cache[key]        self.miss_count += 1        return ""     def put(self, key: str, value: str) -> None:        self.cache[key] = value        self.cache.move_to_end(key)        if len(self.cache) > self.capacity:            self.cache.popitem(last=False)  class OriginServer:    """源站:内容的最终归属地"""    def get(self, key: str) -> str:        return "origin-" + key  class CDN:    """CDN核心:一致性哈希环 + 路由到边缘节点"""    def __init__(self, edges: List[EdgeNode], vnodes: int = 9):        self.vnodes = vnodes        self.ring: Dict[int, EdgeNode] = {}        self.origin = OriginServer()        for edge in edges:            self._add_node(edge)     def _hash(self, key: str) -> int:        md5 = hashlib.md5(key.encode("utf-8")).hexdigest()        return int(md5[:8], 16)  # 取前8位作为32位哈希值     def _add_node(self, edge: EdgeNode) -> None:        for i in range(self.vnodes):            h = self._hash(edge.node_id + "-" + str(i))            self.ring[h] = edge     def _find_edge(self, key: str) -> EdgeNode:        h = self._hash(key)        keys = sorted(self.ring.keys())        for ring_hash in keys:            if ring_hash >= h:                return self.ring[ring_hash]        return self.ring[keys[0]]  # 环形回绕     def fetch(self, key: str) -> Tuple[str, str]:        edge = self._find_edge(key)        value = edge.get(key)        if value:            return value, edge.node_id        value = self.origin.get(key)  # 回源拉取        edge.put(key, value)        return value + "(回源)", edge.node_id  def main():    edges = [EdgeNode("edge-" + c) for c in ["a", "b", "c", "d"]]    cdn = CDN(edges)    keys = ["content-" + str(i) for i in range(20)]    for key in keys:        # 每个key请求3次:第一次回源,后两次命中        for _ in range(3):            cdn.fetch(key)        result, node = cdn.fetch(key)        print(f"{key} -> {result} @ {node}")    total_hits = sum(e.hit_count for e in edges)    total_all = sum(e.hit_count + e.miss_count for e in edges)    print(f"总缓存命中率: {total_hits / total_all:.1%}")  if __name__ == "__main__":    main()
目的:模拟一个包含 4 个边缘节点、9 个虚拟节点的一致性哈希 CDN。每个 key 首次请求回源并回填缓存,后续请求直接命中,最终输出总缓存命中率。
  1. self.cache: Dict[str, str] = OrderedDict()用有序字典实现 LRU 淘汰:每次访问把 key 移到末尾,超容量时弹出最前面的(最久未用)。
  2. def _hash(self, key: str) -> int:把字符串 key 映射为一个 0~2^32−1 的整数,用于定位哈希环位置。
  3. self.ring[h] = edge为每个物理节点生成 9 个虚拟位置,全部放进哈希环字典。
  4. for ring_hash in keys:顺时针寻找第一个大于等于 key 哈希的位置,找到即返回对应节点。
  5. return self.ring[keys[0]]如果哈希环上找不到更大的节点,就回绕到第一个节点(首尾相连成环)。
  6. value = self.origin.get(key)缓存未命中时触发的“回源”操作,从源站取内容。
  7. edge.put(key, value)回源结果回填到边缘节点缓存,下一次请求就能命中。
  8. total_hits / total_all统计所有节点的命中次数占请求总数比例,即为 CDN 整体缓存命中率。

常见误区

误区“CDN 不就是把图片、CSS、JS 复制到各地吗?动态接口它管不了,用不用 CDN 都一样。”

正解现代 CDN 不仅能做动态内容加速——通过专线回源、连接复用和边缘脚本(如边缘计算),可以在靠近用户的位置完成 API 请求的转发与结果缓存。电商大促和直播互动都依赖 CDN 的动态加速能力。就像快递网络不仅送标准包裹,也能做冷链生鲜和同城急送。

为何常见:早期 CDN 确实以静态分发为主,加之讲解资料多拿图片举例,导致人们把“CDN“与”静态缓存”画了等号。

误区“命中率都到 99% 了,说明 CDN 效果拉满,就该这么调!”

正解命中率只是一个中间指标,不是最终目的。如果为了堆高命中率把 TTL 设成一整天,用户看到的一直是过期数据,业务上反而吃亏。正确做法是结合业务容忍度设置 TTL:静态资源可接受长缓存,实时数据必须短 TTL 甚至绕过缓存。高命中率只有在“内容新鲜度达标”的前提下才有意义。

为何常见:运维同学看监控面板时,命中率是最直观的数字,容易形成“数字越大越好”的直觉,忽略了数字背后的业务语义。

误区“加了虚拟节点,哈希环就一定分布均匀了,每个节点负载都一样。”

正解虚拟节点只是显著缓解了数据倾斜,并不能完全消除。如果哈希函数不够散列、虚拟节点数太少,或者 key 的分布本身不均匀(比如热门 key 集中在一个区间),依然会导致部分节点流量偏高。实践中还需要配合负载感知的路由策略,让热点 key 动态迁移。

为何常见:教科书为了说明虚拟节点的优点,常画出均匀分布的理想图景,加上“均衡负载”四个字,容易让人以为这是确定性结论。

误区“CDN 有几百个节点,攻击流量分散到各处就被稀释了,所以上 CDN 就不用怕 DDoS。”

正解CDN 的分布式架构确实能天然稀释部分大流量攻击,并且边缘节点可以拦截畸形请求、启用频率限制,但攻击者同样可以针对特定边缘节点发起精准大流量攻击,或通过重复回源拖垮源站。生产环境仍需在源站加 WAF 和流量清洗服务,多道防线配合。

为何常见:CDN 厂商宣传安全能力时,常把“抵御 DDoS”作为卖点,用户容易将“缓解”理解为“免疫”。

面试题

Q1. CDN 中边缘节点的主要作用是什么?

单选题 · easy

  • A.存储所有内容的完整副本
  • B.就近缓存并快速返回内容← 正确答案
  • C.替代源站执行全部业务逻辑
  • D.只负责域名的 DNS 解析工作

答案:B。边缘节点像前置仓,只缓存热门内容并提供就近加速。A 错在“完整副本”——边缘节点通常只存放热门数据;C 错在业务逻辑留在源站;D 是调度中心的职责,不是边缘节点的核心职能。

Q2. 内容路由中,用户请求首先通过哪个环节被定位到边缘节点?

单选题 · easy

  • A.一致性哈希
  • B.DNS 解析调度← 正确答案
  • C.回源请求
  • D.缓存淘汰

答案:B。用户请求发起的 DNS 解析就是 CDN 调度的第一站,GSLB 在这里根据地理位置和负载返回最优边缘节点 IP。一致性哈希是节点内路由,回源和淘汰都是缓存流程,不承担定位职能。

Q3. 以下关于一致性哈希的说法,正确的有哪些?

多选题 · mid

  • A.节点增减时只需迁移少量数据← 正确答案
  • B.同一个 key 总能映射到同一节点← 正确答案
  • C.虚拟节点可以缓解数据倾斜← 正确答案
  • D.完全消除了所有节点的负载差异

答案:ABC。一致性哈希的核心优点就是确定性(B)和少量迁移(A),虚拟节点改善了均匀性(C)。但分布不可能完全均匀,热点 key 仍会造成差异,D 的“完全消除”过于绝对。

Q4. TTL 设置过短会导致什么直接问题?

单选题 · mid

  • A.缓存命中率下降且回源流量增大← 正确答案
  • B.用户看到过期的旧数据
  • C.边缘节点缓存被填满
  • D.负载均衡策略失效

答案:A。TTL 是缓存内容的“保质期”。过短意味着内容频繁过期,边缘节点不得不反复回源拉新,命中率下降、源站压力上升。B 是 TTL 过长的后果,C 和 D 与 TTL 长短没有直接关系。

Q5. LRU 缓存淘汰算法淘汰的是哪个对象?

单选题 · mid

  • A.最近最少被访问的数据← 正确答案
  • B.最早写入的过期数据
  • C.体积最大的文件数据
  • D.访问频率最低的冷数据

答案:A。LRU(Least Recently Used)淘汰的是“最久没被用过”的数据,追踪的是访问时间。B 是 FIFO,C 是体积优先,D 更接近 LFU(按访问频率)——LFU 淘汰的是访问次数最少的数据。

Q6. 下列哪些情况会触发边缘节点向源站回源?

多选题 · mid

  • A.请求的 key 在本地缓存中不存在← 正确答案
  • B.缓存内容的 TTL 已经过期← 正确答案
  • C.用户浏览器版本过低
  • D.节点需要进行 DNS 解析

答案:AB。缓存未命中和缓存过期是回源的两大触发条件。缓存新鲜且存在时直接命中返回。C 与回源无关,D 是调度环节,二者都不会触发源站请求。

Q7. 一致性哈希中引入虚拟节点的主要目的是?

单选题 · hard

  • A.增加哈希环的密钥安全强度
  • B.提高哈希函数的计算速度
  • C.缓解节点数据分布不均匀← 正确答案
  • D.减少 DNS 调度的响应时间

答案:C。物理节点数量少时,哈希环切分的区间严重不均,虚拟节点让每个物理节点在环上拥有多个“分身”,区间细分后分布更均匀。它不涉及安全、计算速度或 DNS 调度,因此 A、B、D 都不正确。

Q8. CDN 缓存命中率的标准计算方式是?

单选题 · easy

  • A.命中缓存请求数除总请求数← 正确答案
  • B.缓存容量除源站内容总量
  • C.边缘节点数除活跃用户数
  • D.回源请求数除边缘节点数

答案:A。命中率 = 缓存直接命中的请求数 ÷ 总请求数。它衡量 CDN 在多大程度上减轻了源站负担。B 描述的是缓存覆盖率,C 是节点密度,D 是回源比例(与命中率互补但不完全对等)。

Q9. 全局负载均衡(GSLB)进行节点选择时,最主要的依据是什么?

单选题 · mid

  • A.用户地理位置和节点负载状态← 正确答案
  • B.用户浏览器类型和版本信息
  • C.源站数据库的当前连接数
  • D.边缘节点的磁盘空间大小

答案:A。GSLB 是“跨国/跨域选仓库”,关注用户所在地、节点网络质量和实时负载,把请求导航到最近最闲的节点。浏览器版本(B)、源站数据库连接(C)都不在 GSLB 决策范围内;磁盘空间是局部调度才考虑的指标。

Q10. 面试中设计一个高可用 CDN 方案时,下列哪些点值得重点讨论?

多选题 · hard

  • A.多级缓存与 TTL 动态调优← 正确答案
  • B.一致性哈希配合虚拟节点← 正确答案
  • C.多源站容灾与超时重试← 正确答案
  • D.用户手机型号的兼容适配

答案:ABC。缓存策略(A)决定性能的上限,一致性哈希(B)解决路由与数据倾斜,多源站容灾(C)保证可用性——这是 CDN 设计的三角核心。手机型号适配(D)属于客户端开发,与分发网络架构设计无关。