做CDN缓存运维的人几乎都绕不开一个话题:源站内容更新之后,边缘节点上的旧缓存怎么办。直接等TTL自然过期显然太慢,用户可能几分钟甚至几小时都看到旧页面,这时候就需要主动失效手段。BAN就是其中一种被广泛使用的方式,但它内部其实分成了软清除和硬清除两个流派,两者在实现机制、性能开销和适用场景上差别相当大。如果选错了方式,轻则命中率暴跌回源压力飙升,重则缓存被误删引发源站雪崩。这篇文章把两种方式的原理、配置和取舍讲清楚。

先理解BAN的本质:失效标记与物理删除的分界线
BAN这个词来源于Varnish的术语体系,指的是把缓存中的某些对象标记为不可用,而不是直接把文件从存储里抹掉。理解这一点非常关键,因为软清除和硬清除的分界线正是在这里。软清除只做标记,对象还留在缓存存储中,只是后续请求不会再命中它;硬清除则是直接删除缓存对象本身,存储空间被立即释放。
软清除的典型实现是往Varnish的ban列表(ban list)里添加一条规则。这条规则会与缓存中的对象逐一比对,匹配上的对象就被判定为失效。注意,对象本身没有被删除,它依然占据着内存或磁盘空间,直到被LRU淘汰或自然过期。这个设计的好处是BAN操作本身极其轻量,添加一条规则的代价几乎可以忽略,即使缓存里有几十万个对象也不怕。
硬清除则不同,它常见于自建Nginx缓存或某些商业CDN的PURGE接口。以Nginx的第三方模块ngx_cache_purge为例,PURGE请求会直接定位到缓存文件并删除它。这种方式见效彻底,但如果缓存规模庞大,扫描和删除文件会产生明显的磁盘IO开销,在机械盘环境下甚至可能造成短暂的IO阻塞。
Varnish软清除的配置示例与原理分析
来看一个Varnish中标准的软清除配置。下面的VCL代码通过PURGE类型的请求触发BAN,将对应URL的缓存对象标记失效。
vcl 4.0;
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purge_allowed) {
return (synth(405, "Not allowed"));
}
# 软清除:添加ban规则,匹配该URL的对象
ban("req.url == " + req.url + " && req.http.host == " + req.http.host);
return (synth(200, "Banned"));
}
}
sub vcl_hit {
# 命中的对象如果被ban规则标记过,则视为未命中,回源取新内容
if (obj.ttl >= 0s) {
return (deliver);
}
}
这段配置里最核心的是ban()函数调用。它把一条表达式拼接后写入ban列表,之后任何请求进来时,Varnish都会检查命中的对象是否被ban规则覆盖,被覆盖的对象会被当作miss处理,触发回源。这就是软清除的全部逻辑:不删数据,只改判定结果。
软清除有一个常被忽略的坑,叫作悬垂对象(lurker问题之外的内存占用问题)。被ban掉的对象不会主动从存储中消失,如果缓存对象体积大、更新频繁,这些失效对象会持续占用存储空间,直到LRU机制慢慢把它们挤出去。在内存型存储backend下,这可能导致实际可用缓存容量缩水。解决办法是合理设置beresp.ttl和grace参数,让失效对象尽快过期释放。
另一个要点是ban规则的精确度。ban("req.url ~ .png$")这种正则规则一次能失效成千上万个对象,非常高效,但正则写得过宽会误伤大量正常缓存,命中率瞬间归零。生产环境建议精确到host加完整路径,只有在批量更新场景下才使用正则。
Nginx硬清除的实现与性能代价
硬清除在Nginx体系里需要借助ngx_cache_purge模块,编译时加上--add-module参数引入。配置完成后,通过特定URL即可触发删除。
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:100m
max_size=10g inactive=60m;
server {
location / {
proxy_cache my_cache;
proxy_pass http://backend;
}
# 硬清除:直接删除对应的缓存文件
location ~ /purge(/.*) {
allow 10.0.0.0/8;
deny all;
proxy_cache_purge my_cache $host$1;
}
}
访问http://节点地址/purge/目标路径时,模块会根据缓存key计算出文件路径,直接从磁盘上unlink掉该文件。这个操作是真正的物理删除,空间立即回收,后续请求全部回源重建缓存。它的优势是行为确定、不残留垃圾数据,适合缓存对象更新频率低但单对象体积大的场景,比如大文件分发。
硬清除的代价同样明显。第一,每次PURGE都产生磁盘操作,如果一次批量清除上千个文件,机械盘节点可能出现秒级的IO压力;第二,删除后缓存完全为空,突发流量会瞬间打到源站,没有grace机制兜底的话,源站在高并发下容易被打挂。相比之下,软清除天然带有缓冲效果,因为旧对象还在存储里,配合grace甚至可以在回源失败时继续提供旧内容,这是硬清除做不到的容灾能力。
如何选择:按业务特征做决策
选择清除策略时可以从三个维度判断。首先是缓存对象数量:对象数在十万级以上、且更新频繁的站点,软清除的轻量优势非常突出,ban一条规则比删除十万个文件的代价小几个数量级。其次是回源承受能力:源站带宽或性能紧张的站点,优先用软清除加grace的组合,避免硬清除后出现的回源洪峰。最后是存储压力:如果缓存介质容量有限、对象体积大,硬清除的空间回收更彻底,长期运行更干净。
实际生产中两者经常混用。常见做法是常规内容更新走软清除保证性能,大规模改版或缓存污染事件发生时,直接清空整个缓存目录做硬清除兜底。另外无论哪种方式,都要把PURGE接口的访问控制做好,只允许可信内网调用,否则任何人都能删你的缓存,等于把缓存层拱手让给攻击者。缓存清除不是越彻底越好,而是要在一致性、命中率和源站安全之间找到那个平衡点,理解了软与硬的本质差异,这个决策就不难做了。
CDN缓存清除CDN BAN方法Varnish PURGE修改时间:2026-09-11 07:02:40