如何用Varnish 6+在同一服务器实现内存-磁盘两层分级缓存?
Varnish 6+ 内存-磁盘两层分级缓存实现方案
针对你提出的分级缓存需求(256G内存热缓存+1TB SSD冷缓存,基于命中次数自动迁移),以下是具体的VCL配置和启动参数方案:
1. 启动参数配置
首先在启动Varnish时定义两个命名存储后端,明确区分内存和磁盘介质:
varnishd -a :80 -f /etc/varnish/default.vcl -s mem=malloc,256G -s disk=file,/var/lib/varnish/cache_disk.bin,1T
mem:256G内存存储,用于高热度内容disk:1TB SSD文件存储,用于低热度内容
2. VCL核心逻辑实现
(1)请求阶段:优先查询内存缓存
客户端请求进来时,优先从内存存储查找缓存:
sub vcl_recv { set req.storage_hint = "mem"; return (hash); }
(2)哈希阶段:保证缓存键一致性
确保内存和磁盘缓存使用相同的缓存键,支持内容跨存储流转:
sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (lookup); }
(3)命中阶段:触发缓存迁移逻辑
当命中磁盘缓存且命中次数达标时,将内容迁移到内存缓存并更新TTL:
sub vcl_hit { # 磁盘缓存命中次数≥阈值(此处设为5)时,迁移到内存 if (obj.storage == "disk" && obj.hits >= 5) { set beresp.storage_hint = "mem"; set beresp.ttl = 10s; return (restart); } # 内存缓存命中时,维持短TTL if (obj.storage == "mem") { set obj.ttl = 10s; } # 磁盘缓存命中次数未达标时,维持长TTL if (obj.storage == "disk") { set obj.ttl = 2m; } return (deliver); }
(4)未命中阶段:降级查询磁盘缓存
内存缓存未命中时,切换到磁盘存储查找,仍未命中则回源:
sub vcl_miss { set req.storage_hint = "disk"; return (fetch); }
(5)后端响应阶段:初始内容存入磁盘
首次回源的内容默认存入磁盘缓存,设置长TTL:
sub vcl_backend_response { set beresp.storage_hint = "disk"; set beresp.ttl = 2m; # 清除不必要的Set-Cookie头,确保内容可缓存(按需调整) unset beresp.http.set-cookie; return (deliver); }
3. 缓存流转流程
客户端请求 → 内存缓存(命中次数<5时无内容) → 磁盘缓存(首次回源后存储,TTL2min) → 回源获取内容 ↑(命中次数≥5时,缓存自动迁移至内存,TTL10s)
关键调整点
- 命中阈值:可根据业务需求修改
obj.hits >= 5中的数值,比如调整为3或10 - TTL设置:内存缓存TTL(5-10s)和磁盘缓存TTL(2min)可根据内容更新频率灵活调整
- 存储命名:启动参数中的存储名称必须与VCL中的
storage_hint完全对应
内容的提问来源于stack exchange,提问作者Drad
相关产品推荐
相关产品推荐

