总的来说,我提供的文件非常小。想想图像和小视频。使用 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
我在这里遗漏了什么,以避免下载停止? 无论如何,Varnish 是否会以某种方式缓存文件?
注意:HAProxy 在 Varnish 前面运行。Apache 是实际的 Web 服务器。
答案1
计数器
请查看你的储物柜通过使用varnishstat
。
这些计数器可以帮助您了解正在发生的事情:
SMA.s0.g_space
SMA.s0.g_bytes
SMA.Transient.g_bytes
g_space
让你知道可用空间,g_bytes
是正在使用的空间的字节数。SMA
是你的malloc 存储,短暂的指的是不属于缓存大小的瞬时存储。
缓存大小
如果你正在处理的对象是6GB大小,您的-s malloc
设置至少应为大小为 6 GB,否则无法分配空间,并且会崩溃。
如果你的缓存大小刚好大于6 GB在这种情况下,Varnish 必须不断核弹删除缓存中的对象以节省空间。请确保缓存中有足够的空间。
短寿命对象(TTL 为 2 分钟或更短)永远不会在那里结束,并且将占据暂时存储
文件装卸
有一个文件装卸工将使用磁盘来存储对象。如果缓存的总大小超出了您愿意分配给 Varnish 的内存量,则可以使用此方法。
然而,随着时间的推移文件装卸工会降低您的速度,因为它并没有真正为此进行优化。它会受到磁盘碎片的影响,并且性能不佳。
海量存储引擎
为了解决这些存储问题,Varnish Software 创建了海量存储引擎 (MSE)。它能够存储 PB 级的数据,并且以不会出现碎片或延迟的方式写入。
不幸的是,这不是开源的装卸工具。它是 Varnish Enterprise 产品的一部分,需要许可证。但是,我们的官方云映像(在 AWS、Azure、GCP 和 OCI 上)让您有机会使用 Varnish Enterprise,而无需提前购买许可证。
- AWS:https://aws.amazon.com/marketplace/pp/B07L7HVVMF?ref_=srh_res_product_title
- Azure:https://azuremarketplace.microsoft.com/en-us/marketplace/apps/varnish.varnish-enterprise?tab=Overview
- 地源控制点(GCP):https://console.cloud.google.com/marketplace/details/varnish-public/varnish-cache-6-payg-ubuntu?q=varnish&id=6a56f7aa-357c-4032-95c9-ce008bbe534f
- 海外投资处:https://cloudmarketplace.oracle.com/marketplace/en_US/listing/73388855
不要缓存大文件
另一种选择是防止大文件被一起缓存。
显然,根据内容长度排除大文件是行不通的。目前,确保大文件不会消耗对象存储内存的唯一方法是return(pipe)
调用vcl_recv
。
这不是一个理想的解决方案,因为您应该根据传入的请求提前知道响应将会非常巨大。
return(pipe)
是 Varnish 的一个机制,可以绕过缓存,也可以HTTP 模式并进入TCP 模式。这通常用于传入请求看起来不像 HTTP 的情况。