Вопрос или проблема
Я использую Varnish для кэширования статических файлов перед веб-сервером Apache2. Это смесь небольших файлов (CSS/JS/изображения) и больших файлов (от 200 МБ до 2 ГБ).
Я ограничил как временное, так и память malloc в демоне до 8/12 ГБ соответственно:
ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a :8000,PROXY -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,12G -s Transient=malloc,8G
Это, похоже, учитывается при проверке varnishstat
:
SMA.s0.g_bytes 2.67G
SMA.s0.g_space 9.33G
12.00G (всего)
SMA.Transient.g_bytes 3.26G
SMA.Transient.g_space 4.74G
8.00G (всего)
Но не так, когда проверяю top
:
MiB Mem : 32169.8 total, 274.4 free, 30405.1 used, 1490.3 buff/cache
MiB Swap: 16382.0 total, 9683.5 free, 6698.5 used. 1360.4 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3118 vcache 20 0 51.4g 29.3g 1.3m S 7.9 93.2 3:30.05 /usr/sbin/varnishd
Такое использование памяти вызывает обмен данными на сервере, затем приводит к сбоям и в конечном итоге вызывает oom-killer
для уничтожения демона Varnish.
Сервер – это виртуальная машина с 32 ГБ памяти. Я также пробовал с другими ограничениями transient/malloc и передачей больших файлов, но поведение не изменилось.
В чем может быть проблема?
VCL:
backend default {
.host = "127.0.0.1";
.port = "8001";
}
sub vcl_recv {
unset req.http.X-Cache-Request;
// Удалить куки и указать, что этот запрос должен быть кэширован
if (req.http.host ~ "^static.example.com(:\d+)?$"){
unset req.http.Cookie;
set req.http.X-Cache-Request = "1";
}
}
sub vcl_backend_response {
// Установить TTL, если запрос, который должен быть кэширован, и код состояния 2xx, 3xx или 4xx
if (
bereq.http.X-Cache-Request
&& beresp.status >= 200 && beresp.status < 500
&& beresp.http.Cache-Control !~ "no-cache"
){
unset beresp.http.Set-Cookie;
set beresp.ttl = 1w;
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
Мне интересно, нашли ли вы какое-либо объяснение утечке памяти?
У меня такая же ситуация с Varnish 7 и сервером на 32 ГБ, память malloc установлена на 16 ГБ, в то время как процесс varnish потребляет 29 ГБ.
Спасибо
Ответ или решение
Использование Varnish для кэширования статических файлов перед веб-сервером Apache2 может вызывать различные вопросы и проблемы, особенно в отношении управления памятью. Рассмотрим основные причины, по которым Varnish может потреблять больше памяти, чем заданные лимиты, даже после установки как временных, так и динамических ограничений.
1. Архитектура Varnish
Varnish использует систему управления памятью (SMA – Storage Memory Allocator), которая предназначена для оптимизации работы с кэшем. Ваша конфигурация:
-s malloc,12G -s Transient=malloc,8G
означает, что вы выделяете 12 ГБ для основной памяти (malloc) и 8 ГБ для временной памяти (Transient). Однако важно понимать, что эти ограничения не всегда гарантируют жесткое распределение памяти, и Varnish может использовать дополнительные ресурсы в зависимости от нагрузки, структуры данных и обработки кэша.
2. Утечки памяти
Одной из причин чрезмерного потребления памяти в Varnish может быть наличие утечек памяти. Утечка памяти возникает, когда память, выделенная процессом, не освобождается после завершения работы с данными. Это может произойти по нескольким причинам:
- Неправильная обработка запросов и ответов: Ваша VCL-логика может приводить к накоплению объектов в кэше без должной очистки.
- Сложные объекты: Если Varnish кэширует большие файлы (например, изображения, видео), это может значимо повлиять на использование памяти, так как большие объекты занимают больше места, и даже если их TTL истек, они могут оставаться в памяти.
3. Конфигурация VCL и TTL
Смотрите на блочные конфигурации вашей VCL. Например:
if (beresp.http.Cache-Control !~ "no-cache") {
set beresp.ttl = 1w;
}
Вы устанавливаете TTL в 1 неделю, что означает, что объекты будут оставаться в кэше много времени. Если у вас есть высокие объемы доступа к статическим файлам, это может привести к накоплению большого количества объектов, что увеличивает использование памяти. Рекомендуется периодически пересматривать настройки TTL и учитывать, что слишком долгий кэш может привести к высокому потреблению памяти.
4. Использование других модулей и системных ресурсов
Помимо настроек Varnish, важно обратить внимание на другие запущенные процессы в вашей среде. Как видно из вашего запроса, Varnish использует значительное количество ресурсов:
%MEM 93.2
Это может указывать на недостаток системных ресурсов или конфликты с другими процессами, которые также используют память.
5. Способы диагностики и оптимизации
-
Мониторинг: Используйте
varnishstat
, чтобы следить за использованием кэша и его состоянием. АнализируйтеSMA
показатели, чтобы выявить узкие места. -
Настройка VCL: Подумайте о том, чтобы уменьшить TTL для больших объектов или выбрать различные настройки кэша для разных типов контента.
-
Ограничение файлов: Для очень больших файлов (например, от 200 МБ до 2 ГБ) может быть разумным установить отдельные исходные правила в вашей VCL, чтобы этого содержимого не кэшировать вовсе или использовать
pipe
илиfetch
. -
Переход на улучшенные версии: Если вы используете Varnish 7, рассмотрите возможность обновления или использования безработных
vsl
для отслеживания потребления памяти и других аспектов производительности. -
Файловая система кэша: Подумайте о переходе на файловую систему кэша, которая могла бы снизить потребление оперативной памяти в ситуациях с крупными файлами.
Заключение
Чрезмерное использование памяти Varnish требует детального анализа и оптимизации как конфигураций Varnish, так и VCL. Применяя описанные рекомендации и подходы, у вас будет возможность существенно улучшить производительность и стабильность вашего кэширования.
Спецификация и детальная оптимизация конфигурации могут оказать значительное влияние на расход памяти вашего Varnish-сервера и предотвратить проблемы, такие как использование подкачки и вмешательство механизмов OOM-killer.