Гайд: Тюнинг подсистемы виртуальной памяти Linux: параметры vm.swappiness, vm.dirty_ratio, vm.vfs_cache_pressure
Архитектура подсистемы управления виртуальной памятью ядра Linux (MM Subsystem)
Подсистема управления памятью ядра Linux (Virtual Memory Manager) балансирует между анонимными страницами процессов (Anonymous Memory), дисковым кэшем страниц (Page Cache) и структурами каталогов ядра (Dentry/Inode Cache). Поведение ядра по сбросу измененных («грязных») страниц на диск и вытеснению памяти в раздел подкачки (Swap) регулируется глобальными системными параметрами sysctl vm.*. При неверных настройках по умолчанию серверы под высокой нагрузкой сталкиваются с критическими деградациями:
- I/O Spikes / I/O Stalls: Ядро внезапно замораживает все процессы на несколько секунд для экстренного сброса гигабайтов грязного кэша на медленные диски;
- Swap Thrashing: СУБД (PostgreSQL, MySQL, Redis) вытесняется в swap даже при наличии свободного дискового кэша в RAM;
- Агрессивный сброс кэша файловой системы: Частые дисковые чтения метаданных файлов из-за чрезмерной очистки структур inode/dentry.
Бизнес-риски
Рост latency транзакций СУБД с 2 мс до 15 000 мс, задержки в обработке очередей сообщений, падение RPS веб-приложений.
Ключевые параметры тюнинга подсистемы VM
| Параметр sysctl | Значение по умолчанию | Назначение и влияние |
|---|---|---|
vm.swappiness | 60 | Агрессивность вытеснения анонимных страниц в Swap (0 — избегать подкачки до последнего, 100 — агрессивный swap). |
vm.dirty_ratio | 20 (%) | Процент системной памяти, занятой грязным кэшем, при котором блокируются пишущие процессы для синхронного сброса на диск. |
vm.dirty_background_ratio | 10 (%) | Процент грязной памяти, при котором фоновый демон kworker/flush начинает асинхронный сброс данных на диск. |
vm.vfs_cache_pressure | 100 | Приоритет освобождения кэша метаданных VFS (директории/иноды) относительно дискового page cache. |
Регламент профилирования и настройки параметров виртуальной памяти
Сценарий 1: Тюнинг параметров сброса грязных страниц (Flush Dirty Pages) для серверов баз данных
На серверах с большим объемом RAM (например, 128–512 Гб) дефолтный dirty_ratio = 20% означает, что в памяти может накопиться более 100 Гб не записанных на диск данных, сброс которых полностью парализует дисковую подсистему:
# 1. Проверка текущего объема грязных страниц в оперативной памяти прямо сейчас:
cat /proc/meminfo | grep -E "Dirty|Writeback"
# 2. Для серверов с большими объемами памяти (>= 64G) лучше использовать абсолютные байты вместо процентов:
sudo sysctl -w vm.dirty_background_bytes=67108864 # Начинать фоновый сброс при накоплении 64 МБ
sudo sysctl -w vm.dirty_bytes=536870912 # Блокировать процессы только при накоплении 512 МБ
# Либо для серверов среднего класса (через низкие проценты):
sudo sysctl -w vm.dirty_background_ratio=5
sudo sysctl -w vm.dirty_ratio=10Сценарий 2: Оптимизация vm.swappiness для СУБД и Redis
Для предотвращения задержек вытеснения рабочих процессов баз данных в swap:
# Для серверов баз данных (MySQL, PostgreSQL, MongoDB, Elasticsearch, Redis):
sudo sysctl -w vm.swappiness=1
# (Значение 1 заставляет ядро свопировать только в случаях абсолютной нехватки RAM, исключая OOM-killer)Сценарий 3: Настройка vm.vfs_cache_pressure для серверов с миллионами файлов
Если на сервере работает Git, файловые хранилища или кэши статики с огромным количеством мелких файлов:
# Уменьшение агрессивности сброса структуры директорий (удерживать dentry/inode в памяти):
sudo sysctl -w vm.vfs_cache_pressure=50Сценарий 4: Персистентное сохранение конфигурации в sysctl.d
sudo tee /etc/sysctl.d/99-vm-tuning.conf <<EOF
# Оптимизация виртуальной памяти для высоконагруженных HighLoad серверов
vm.swappiness = 1
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
vm.vfs_cache_pressure = 50
vm.overcommit_memory = 1
EOF
sudo sysctl --systemТиповые ошибки администраторов
- Полное отключение swap (swapoff -a) при vm.swappiness = 0: Полное отсутствие файла подкачки лишает ядро пространства для вытеснения неиспользуемых системных страниц, что при малейшем пике трафика приводит к мгновенному убийству СУБД через
OOM-Killer. Рекомендуется иметь небольшой Swap (1–4 Гб) даже на мощных серверах приvm.swappiness = 1. - Установка dirty_background_ratio выше dirty_ratio: Противоречивая конфигурация, вызывающая непредсказуемое поведение планировщика сброса памяти.
Эксперты ITSTM проведут глубокое профилирование подсистемы памяти, устранят дисковые задержки сброса страниц и настроят сбалансированные параметры sysctl.
Частые вопросы (FAQ)
Что означает параметр vm.overcommit_memory = 1?
В режиме 1 ядро всегда разрешает выделение памяти процессам авансом (необходимо для работы фонового сохранения BGSAVE в Redis). Значение 2 запрещает выделение памяти сверх лимита commit_limit.
Почему после очистки кэша (drop_caches) сервер начинает тормозить?
Команда echo 3 > /proc/sysrq-trigger или drop_caches уничтожает разогретый Page Cache и VFS кэш. Все последующие запросы вынуждены обращаться к физическому диску, вызывая резкий скачок I/O.
Чем отличаются параметры dirty_expire_centisecs и dirty_writeback_centisecs?
dirty_expire_centisecs (дефолт 3000 = 30 сек) задает возраст страницы, после которого она помечается на запись. dirty_writeback_centisecs (дефолт 500 = 5 сек) задает периодичность пробуждения фоновых демонов сброса.
Как проверить эффективность работы кэша страниц Linux?
Используйте утилиту fincore из пакета linux-ftools или bcache-tools для отслеживания процента попаданий страниц файлов в оперативную память.