我使用清漆作为网络缓存。我在 RHEL 9.2 上运行。我的缓存大小为 1GB。我的清漆进程使用的是3.7G内存。
$ ps -p 1163 -o %mem,rss
%MEM RSS
15.7 3886108
我正在使用
-s malloc,1024M
参数运行 varnish,这应该将缓存大小设置为 1GB。由 systemd 调用的完整命令是:
/usr/sbin/varnishd -a 127.6.6.6:7480 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,1024M -P /var/run/varnish.pid -T 127.6.6.6:62
看起来正在工作,我可以用
varnishstat
看到:
$ varnishstat -1 | grep s0.g
SMA.s0.g_alloc 22573 . Allocations outstanding
SMA.s0.g_bytes 1073105012 . Bytes outstanding
SMA.s0.g_space 636812 . Bytes available
我很难相信 1GB 缓存有 2.7GB 的开销,我在这里错过了什么?
使用
systemctl restart varnish
重新启动会暂时降低使用量(因为它会清空缓存,但非缓存内存也会消失),但它会逐渐再次增加并稳定在 3.7GB。
这是一个负载较重的测试系统,该内存是否可能真正用于服务请求?我可以在短暂的空间中看到这一点,在我看来,这看起来很无趣,但在阅读了其他一些线程后,也许确实如此。
SMA.Transient.c_req 9720800 7.90 Allocator requests
SMA.Transient.c_fail 0 0.00 Allocator failures
SMA.Transient.c_bytes 324751584558 263852.57 Bytes allocated
SMA.Transient.c_freed 324751584558 263852.57 Bytes freed
SMA.Transient.g_alloc 0 . Allocations outstanding
SMA.Transient.g_bytes 0 . Bytes outstanding
SMA.Transient.g_space 0 . Bytes available
我还看到一些建议说varnish是设计用于jemalloc的,我没有安装jemalloc,看起来varnish正在使用glibc的malloc。
malloc
缓存存储仅代表Varnish内存消耗的一部分。
正如您在问题中提到的,瞬时存储也会消耗内存。临时存储用于缓冲或流式传输不可缓存和短暂的内容。它是无界的,这意味着在出现尖峰的情况下可能会导致 OOM。
仅供参考:
shortlived
运行时参数定义什么是短暂内容,默认为 10 秒。
还有 Varnish 的运行时成本。对于每个线程,都会发生一些内存分配。
线程数量受到每个线程池的
thread_pool_min
和 thread_pool_max
运行时参数的限制。默认情况下,每个线程池的这些值最小值为 100,最大值为 5000。
由于有 2 个线程池(由
thread_pools
定义),如果您依赖默认值,它将在 200 到 1000 之间。
workspace_thread
运行时参数定义每个线程消耗的初始内存量。默认值为 2 KB。
除了每个线程的
workspace_thread
内存消耗之外,每个线程还有额外的内存消耗,具体取决于其正在处理的工作负载类型。
如果线程用于管理 TCP 会话,则默认额外消耗 0.75k 内存,如
workspace_session
运行时参数所定义。
如果使用线程处理 HTTP 请求,则默认消耗 96k 内存,由
workspace_client
运行时参数定义。
对于后端请求,内存消耗由
workspace_backend
运行时参数定义,该参数也默认为 96k。
如果您更改了我提到的任何运行时参数,它将对总内存消耗产生影响。
您可以自由地相应地调整这些参数,这在确保您有足够的线程来处理所有传入请求和后端请求之间是一个非常平衡的行为。
而且还要有足够的内存来处理您在 VCL 文件中指定的所有逻辑。
另一种解决方案是海量存储引擎,它是 Varnish Enterprise(Varnish 的商业版本)的一部分。它有一个称为“内存调控器”的功能,它能够限制 Varnish 的总内存消耗,并根据所需的运行时内存自动缩放缓存的大小。