这是我的 Varnish 配置:
/usr/sbin/varnishd \
-a 127.0.0.1:6081 \
-T 127.0.0.1:6082 \
-f /varnish/default.vcl \
-P %t/%N/varnishd.pid \
-s malloc,4G \
-p thread_pools=12 -p thread_pool_min=250 -p default_ttl=1 -p default_grace=0 -p timeout_idle=1800
因此 12 * 250 = 3000 个线程。使用此设置,我最终打开了超过 400k 个文件。
将线程数减少到最低限度确实会大大减少打开文件的数量。
问题是:这怎么可能?每个 Varnish 线程打开这么多文件是正常的吗?
最佳答案
1
您设置的某些参数可能是导致打开文件数量过多的原因。
线程
让我们从 开始thread_pools=12
。默认值为 2,我们不建议您更改它。虽然在您的用例中thread_pool_min
设置为250
,但 的默认thread_pool_max
值为5000
。
问题是:“在高峰流量期间,或者甚至在活动线程数远低于 1000 个时,您是否看到 40 万个打开的文件?”
仅供参考:
MAIN.threads
计数器varnishstat
可以帮助您确定有多少个活动线程。
假设这种情况发生在绝对峰值流量期间,每个池有 5,000 个线程,但 12 个线程池产生 60,000 个活动线程。
这意味着每个线程大约有 7 个文件描述符,这并不不合理。
影响timeout_idle
当然,还有一个参数,你可以将其从 5 增加到 1800。这意味着,如果设置了keepalive,则连接将空闲 1800 秒,然后关闭。
那真是很长一段时间了。
空闲连接的文件描述符从线程中移出,并由等待线程管理。这意味着文件描述符被保留,而线程可以接受新的连接并创建更多的文件描述符。
仅供参考:您可以运行
varnishstat -f "WAITER.*.conns" -f "MAIN.sess_conn" -f "MAIN.backend_conn"
来监视由服务员线程处理的连接、常规传入连接和后端连接。
需要进行更多调试
在我的回答中,我假设 400k 个打开的文件发生在高峰流量期间。如果不是这样,则需要进行更多调试才能确定哪些文件(或文件描述符)正在使用中。
其中一种方法是运行以下命令:
lsof -p $(pgrep cache-main)
此命令将列出该进程正在使用的各种文件描述符。
当然,运行以下命令并结合参数来列出所有线程和连接:
varnishstat -f "MAIN.threads" -f "WAITER.*.conns" -f "MAIN.sess_conn" -f "MAIN.backend_conn"
3
-
谢谢你的回答。我设置
thread_pools=12
为减少锁争用(我的服务器上有 12 个核心)。Varnish 手册建议此值不应大于核心数。设置thread_pool_min=1500
和thread_pools=2
结果为打开文件数相同。我提到的 400k 个打开文件不是在高峰流量期间:它是永久的。我有一个没有流量的备份服务器,我仍然有超过 400k 个打开文件。lsof -p $(pgrep cache-main) | wc -l
仅返回 ~150。
– -
另外,关于
timeout_idle
:这是因为我有一个本地 NGINX 为客户端提供服务,并且只将 EXPIRED 请求转发给 Varnish,因为 Varnish 可以压缩 EXPIRED 请求。Varnish 只接受来自本地 NGINX 的连接(因此选项 -a 和 -T)
–
-
事实上,在我的主服务器上,
timeout_idle
没有设置(默认为 5 秒),我将其设置为 1800 进行一些测试。不过,使用默认值时,我仍然有同样多的打开文件
–
|
|