CDN 调度策略:三种核心方法
这一讲我们聊聊 CDN 调度策略。说白了,就是怎么把用户拽到最近的节点。
我见过不少团队,上来就搞 Geo 调度,觉得地图上离得近就是快。结果呢?延迟反而变高了。为什么?因为物理距离和网络距离,其实是两码事。
我个人习惯,先把三种策略吃透,再看场景选方案。你想想看,调度策略不对,后面缓存、加速全白搭。
基于地理位置调度
这是最直觉的方案。用户 IP 一过来,查归属地,然后分配最近的节点。
具体怎么干?
- GeoIP 数据库:维护一份 IP 段到地理位置的映射表。
- 静态分配:用户在北京,就给北京节点;用户在纽约,就给纽约节点。
缺点:IP 归属地可能不准。跨运营商调度更是灾难,比如电信用户被分到了联通节点。
我记得有一次,某客户反馈华南地区用户访问奇慢。我查了下调度日志,发现那些用户的 IP 被 GeoIP 误判成了华北,全打到了北京节点。广州到北京,跨了半个中国,延迟当然高。
避坑指南:我曾经用过一个第三方 GeoIP 库,结果大量海外 IP 被判定为国内。后来我养成了习惯,一定要搭配纯真 IP 库或者 MaxMind 的商业库做交叉校验。
另外,Geo 调度很难处理移动网络。用户在地铁上,IP 归属地可能是另一个城市。你想想看,这种场景下纯靠 Geo 调度,基本就是碰运气。
| 维度 | Geo 调度 | 说明 |
|---|---|---|
| 数据源 | IP 归属地库 | 需要定期更新 |
| 动态性 | 无 | 分配结果固定 |
| 适用场景 | 静态资源、跨洲缓存 | 对延迟不敏感的场景 |
基于网络延迟调度
这才是真正意义上的「就近」。我不看你在地图上离我多远,我只看你到我各个节点的网络延迟是多少。
怎么做?
- 探测节点:在 CDN 边缘节点部署探测程序。
- 主动探测:定时向用户 IP 或用户附近的 DNS 发送 ICMP/HTTP 探测包。
- 被动采集:收集真实用户连接时的握手延迟、建连时间。
- 动态建表:维护一张「用户 IP 段 → 各节点 RTT」的延迟表。
调度时直接查这张表,挑 RTT 最小的节点返回。
小技巧:我建议不要只依赖单次探测。网络抖动很常见,可以用滑动窗口取过去 5 分钟的 P99 延迟,这样更稳定。
延迟调度的精度高,但成本也高。你想想看,全球几百个节点,每个节点都要维护一张延迟表,数据量巨大。而且用户 IP 在变,探测不能停。
我经历过一个案例:某游戏公司用纯延迟调度,结果华北用户被分配到了华南节点。为什么?因为当时华南节点一条海底光缆断了,但探测程序没感知到,RTT 数据还是老的。直到用户投诉,我们才发现延迟表更新有 10 分钟的误差。
避坑指南:我曾经因为探测间隔设置太长,导致延迟表严重滞后。后来我把探测周期从 5 分钟改成了 30 秒,误调度率降了 70%。
# 探测逻辑伪代码
def select_best_node(user_ip):
delay_table = get_delay_table()
# 取过去5分钟 P99 延迟
min_rtt = float('inf')
best_node = None
for node in all_nodes:
rtt = delay_table.get_p99(user_ip, node)
if rtt < min_rtt:
min_rtt = rtt
best_node = node
return best_node
基于负载的调度
前面两种策略只考虑「离得近」,但没考虑「挤不挤」。你想想看,如果某个节点快被挤爆了,就算离得再近,用户体验也一塌糊涂。
负载调度要解决的就是这个问题。
- 实时采集:每个节点上报 CPU、内存、带宽使用率、并发连接数。
- 负载权重:根据健康度给节点打分。
- 流量分配:把新用户优先调度到低负载节点。
我记得在某大促期间,华东节点因为带宽打满,响应时间飙升到了 2 秒。如果只看延迟,它可能还是离用户最近的。但负载调度及时发现健康度下降,把流量切到了华中节点,整体延迟反而降到了 300 毫秒。
负载调度一般和前面两种策略组合使用。我的做法是:先用 Geo 或延迟选出一批候选节点,再根据负载评分做二次筛选。这样既保证了物理距离不绕路,又避免了单节点过载。
| 策略 | 数据源 | 动态性 | 适用场景 |
|---|---|---|---|
| Geo 调度 | IP 库 | 低 | 静态资源、跨洲 |
| 延迟调度 | 网络探测 | 中 | 动态内容、视频 |
| 负载调度 | 节点指标 | 高 | 高并发、大促 |
总结一下我的经验:
- 纯 Geo:简单但粗糙,适合不差钱、用户分布广的场景。
- 纯延迟:精度高,但代价大,延迟表更新要快。
- 加负载:防止雪崩,特别是大流量时一定要加。
你想想看,一个用户跑了几千公里到你的 CDN 节点上,结果那个节点快挂了。这不白费力气吗?所以我的建议是:延迟做初筛,负载做终选。
一句话总结:没有完美的调度策略,只有适合业务的组合方案。不要只盯着一种策略,多维融合才是最优解。
好了,这部分我们先聊到这。实际项目中,你可以根据业务特点组合使用这些策略。