Ubuntu22.04下Varnish7.0.3 Transient存储内存持续增长问题排查
Varnish Transient存储内存持续增长问题诊断与解决
核心问题分析
你遇到的是Varnish Transient存储内存泄漏问题,表现为:
- 无内存限制时耗尽服务器内存与swap,进程被OS终止;配置
-s Transient=malloc,512m后,内存仍涨至上限,不可缓存页面返回503,且Varnish总内存超配置值。 varnishstat显示SMA.Transient.c_bytes(内存流入量)远大于c_freed(释放量),内存持续累积。
可能原因
- libjemalloc 5.2.1内存回收缺陷:Varnish依赖jemalloc做内存分配,5.2.1版本在频繁创建/销毁Transient对象的场景下,存在内存无法及时归还给系统的bug,Varnish官方已在5.3.0及以上版本修复该问题。
- VCL配置逻辑问题:如果VCL中频繁生成Transient对象却未正确处理生命周期(比如错误保留对象引用、对不可缓存请求误用缓存指令),会导致内存无法回收。
- Magento动态请求特性:Magento大量不可缓存请求(如购物车、结账页)会存入Transient存储,若内存回收机制失效,会快速耗尽配额。
解决方案
1. 升级libjemalloc至5.3.0+
Ubuntu 22.04默认的libjemalloc2是5.2.1,需手动升级:
编译安装步骤:
# 安装编译依赖 sudo apt-get install build-essential autoconf libtool -y # 从jemalloc官方渠道下载5.3.0版本源码包并解压 tar -xf jemalloc-5.3.0.tar.bz2 cd jemalloc-5.3.0 # 编译配置 ./autogen.sh ./configure --prefix=/usr/local make -j$(nproc) sudo make install # 更新系统库缓存 sudo ldconfig
配置Varnish使用新jemalloc:
编辑/etc/systemd/system/varnish.service,在ExecStart行上方添加环境变量:
Environment="LD_PRELOAD=/usr/local/lib/libjemalloc.so.2"
重载并重启服务:
sudo systemctl daemon-reload sudo systemctl restart varnish
验证版本:
ldd $(which varnishd) | grep jemalloc
输出若显示libjemalloc.so.2 => /usr/local/lib/libjemalloc.so.2,则升级成功。
2. 检查优化VCL配置
- 排查不必要的Transient对象生成:比如在
vcl_recv中是否对不可缓存请求误用std.cache_req_body,这类操作会强制将请求体存入Transient存储,尽量避免。 - 确保Transient对象生命周期正确:在
vcl_backend_response中,对不可缓存响应不要设置beresp.do_esi等会延长对象生命周期的属性。 - 清理自定义逻辑:检查是否有错误标记(如
set req.http.X-Transient)导致Varnish错误保留Transient对象。
3. 调整Transient存储回收参数
在varnish.service的ExecStart中添加以下参数,强制触发内存回收:
-p sma_transient_max_size=10m -p sma_transient_min_free=20m
sma_transient_max_size:限制单个Transient对象的最大大小,避免大对象占用过多内存。sma_transient_min_free:当Transient存储剩余内存低于20m时,触发强制回收。
效果验证
调整后持续观察varnishstat的SMA.Transient.c_bytes和c_freed指标,若两者差值逐渐缩小并趋于稳定,说明内存回收机制恢复正常。
内容的提问来源于stack exchange,提问作者Pedro Bernardo
相关产品推荐
相关产品推荐

