计数器

计数器

总的来说,我提供的文件非常小。想想图像和小视频。使用 Varnish 缓存这些文件轻而易举,不会给我带来任何问题。

我遇到的问题是,当我下载一个 6 GB 的文件时。在下载过程中,我看到 Varnish 使用的内存不断增加,直到崩溃。然后它重新启动,直到再次崩溃。

  1. 我想避免 Varnish 崩溃
  2. 因此每次下载都会暂停,而且速度非常慢。它应该只下载 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,而无需提前购买许可证。

不要缓存大文件

另一种选择是防止大文件被一起缓存。

显然,根据内容长度排除大文件是行不通的。目前,确保大文件不会消耗对象存储内存的唯一方法是return(pipe)调用vcl_recv

这不是一个理想的解决方案,因为您应该根据传入的请求提前知道响应将会非常巨大。

return(pipe)是 Varnish 的一个机制,可以绕过缓存,也可以HTTP 模式并进入TCP 模式。这通常用于传入请求看起来不像 HTTP 的情况。

相关内容