总的来说,我提供非常小的文件。想想图片和小视频。用 Varnish 缓存这些就像轻而易举,不会给我带来任何问题。
我遇到的问题是当我下载一个 6 GB 的文件时。这样做时,我看到 Varnish 使用的内存一直在上升,直到它崩溃。然后它重新开始,直到它再次崩溃。
- 我想避免 Varnish 崩溃
- 下载因此每次都暂停并且非常慢。它应该只下载 6 GB 的文件。时期。
我已经尝试过文件和 RAM 缓存存储,但没有什么不同。通过设置瞬态内存,我能够避免崩溃;
DAEMON_OPTS="-s Transient=malloc,512m"
但是,这只会导致 Varnish 使用 512MB 的那一刻,之后它会再次崩溃。
vcl_backend_response
作为测试用例,我已经尝试过
if (std.integer(beresp.http.Content-Length, 0) > 5242880) {
set beresp.do_stream = true;
return (deliver);
}
和
if (std.integer(beresp.http.Content-Length, 0) > 5242880) {
set beresp.uncacheable = true;
return (deliver);
}
但是,这些都不能确保使用我的浏览器很好地下载了文件。
VarnishLog 抛出此错误,但我想这只是意味着内存已满并因此崩溃。
FetchError Could not get storage
我在这里错过了什么,以避免下载被停止?清漆是否以某种方式缓存文件?
注意:HAProxy 运行在 Varnish 前面。Apache 是实际的 Web 服务器。
计数器
请使用.查看您的存储计数器
varnishstat
。这些计数器将帮助您了解正在发生的事情:
g_space
让您知道可用空间,并且g_bytes
是正在使用的空间字节数。SMA
是您的malloc storage,Transient是指不属于您的缓存大小的临时存储。缓存大小
如果您正在处理大小为6GB的对象,您的
-s malloc
设置应至少为6 GB 大小,否则无法分配空间,它会在您身上崩溃。如果在这种情况下您的缓存大小仅略大于6 GB,Varnish 将不断地从缓存中删除对象以节省空间。请确保里面有足够的东西。
TTL 为 2 分钟或更短的短期对象永远不会结束,并且会占用瞬态存储
文件装卸工
有一个文件 stevedore将使用磁盘来存储对象。如果缓存的总大小超过了您愿意分配给 Varnish 的内存量,则可以使用此选项。
但是,随着时间的推移,文件 stevedore会减慢您的速度,因为它并没有真正为此进行优化。它会受到磁盘碎片的影响,并且没有很好的性能。
海量存储引擎
为了解决这些存储问题,Varnish Software 创建了海量存储引擎 (MSE)。它能够存储 PB 级的数据,并且其编写方式不会受到碎片或延迟的影响。
不幸的是,这不是一个开源的搬运工。它是 Varnish Enterprise 产品的一部分,需要许可证。但是,我们的官方云映像(在 AWS、Azure、GCP 和 OCI 上)让您有机会使用 Varnish Enterprise,而无需提前购买许可证。
不要缓存大文件
另一种选择是防止大文件被缓存在一起。
显然,根据内容长度排除大文件是行不通的。目前,确保大文件不消耗对象存储内存的唯一方法是调用
return(pipe)
.vcl_recv
这不是一个理想的解决方案,因为您应该根据传入的请求提前知道响应将是巨大的。