Тюнинг ядра Linux через sysctl: что реально ускоряет сервер, а что миф
Привет! Я Евгений Семёнов, директор ITFresh. С Linux-серверами я работаю уже больше 15 лет, причём постоянно. Представляете, с чего я начинал? С тупого копирования sysctl-параметров со Stack Overflow – даже не особо вникал, что они там делают. А теперь? Сейчас я настраиваю их осознанно, под конкретную задачу и нагрузку. И вот что я вам сразу скажу: огромное количество тех самых «магических» sysctl-конфигов, что гуляют по сети, на современных ядрах просто бесполезны. Или, что гораздо хуже, они могут реально навредить вашей системе! Поймите, по-настоящему тонкая настройка — это всегда строгий цикл: сначала мы замеряем текущие показатели. Затем меняем ровно один, единственный параметр. И только потом снова замеряем результат. Делать иначе? Это прямой путь получить не улучшение, а совсем наоборот – результат будет хуже, чем было по умолчанию. Проверено.
Три правила тюнинга, которые спасут вам нервы
Прежде чем лезть в /etc/sysctl.d/, зафиксируйте принципы. Я всегда говорю это новым инженерам:
- Не копируйте конфиги вслепую. Параметры, хорошие для узла Kafka с 40-гигабитной сетью, вредны для офисного файл-сервера.
- Измеряйте до и после. Без цифр по RPS, латентности, throughput вы не узнаете, помогло ли.
- Меняйте по одному параметру. Если поменяли пять — и сервер заработал лучше, вы не знаете, какой из пяти помог. Если стал хуже — какой сломал.
Отдельно оговорюсь про современные ядра. Начиная с Linux 5.15, дефолты стали разумными для большинства случаев. Параметры вроде net.ipv4.tcp_tw_reuse, которые раньше советовали ставить в 1, теперь и так в 1. Не трогайте то, что уже настроено правильно.
Где живут настройки sysctl
Итак, где же мы ищем эти самые параметры ядра? Их, как правило, можно найти в трёх местах:
/etc/sysctl.conf— исторический файл, сейчас почти не используется напрямую./etc/sysctl.d/*.conf— основное место для пользовательских настроек. Файлы применяются в алфавитном порядке, поэтому имена вроде50-network.confи99-override.conf./run/sysctl.d/и/usr/lib/sysctl.d/— системные, не трогать.
# Посмотреть текущее значение
sysctl net.ipv4.tcp_congestion_control
# Временное изменение (до ребута)
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
# Постоянное (в файле)
echo 'net.ipv4.tcp_congestion_control = bbr' | \
sudo tee /etc/sysctl.d/99-network.conf
sudo sysctl -p /etc/sysctl.d/99-network.conf
Сетевые параметры для нагруженного сервера
Тут находится самая популярная область для тюнинга. Если речь идёт о веб-сервере, который держит нагрузку от 500 RPS и выше, мы обычно начинаем с такого:
# /etc/sysctl.d/60-network-tuning.conf
# Buffers
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.ipv4.tcp_rmem = 4096 1048576 16777216
net.ipv4.tcp_wmem = 4096 1048576 16777216
# Connection handling
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_syn_backlog = 8192
# TIME_WAIT
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
# Congestion control
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# Ports
net.ipv4.ip_local_port_range = 10000 65535
# Keepalive
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 4
Каждый параметр объясню коротко. rmem/wmem — буферы сокетов, увеличиваем, чтобы на быстрых сетях не было блокировок. somaxconn — длина очереди accept, должна совпадать с backlog в nginx/HAProxy. bbr — современный congestion control от Google, на большинстве нагрузок быстрее cubic. ip_local_port_range — диапазон эфемерных портов, расширяем для прокси-серверов с тысячами исходящих соединений.
Память и vm.swappiness
И сразу же давайте развенчаем миф номер один: «На серверах swap не нужен, отключайте его скорее!» Это, мягко говоря, неправда. Swap — это очень полезный буфер на случай, когда память вдруг «подскочит». Без него OOM-killer просто безжалостно прибьёт ваши процессы, и прощай стабильность. Но есть нюанс: swappiness, конечно, должен быть низким.
# /etc/sysctl.d/50-memory.conf
vm.swappiness = 10
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
vm.vfs_cache_pressure = 50
vm.overcommit_memory = 0
vm.min_free_kbytes = 131072
Для серверов с базами данных мы ставим `vm.swappiness = 10`. Что это даёт? Страницы, которые используются редко, могут спокойно уходить в swap, но при этом активная рабочая память остаётся нетронутой. Никогда! А `vm.dirty_ratio`? Он отвечает за процент «грязных» страниц перед тем, как система принудительно их синхронизирует. На SSD-серверах я обычно снижаю его значение. Почему? Чтобы избежать тех самых неприятных, больших зависаний во время `fsync`.
Сравнение параметров под разные роли
| Параметр | Веб-сервер | PostgreSQL | Прокси/NAT |
|---|---|---|---|
| net.core.somaxconn | 65535 | 8192 | 65535 |
| net.ipv4.tcp_fin_timeout | 15 | 30 | 10 |
| vm.swappiness | 10 | 1 | 10 |
| vm.dirty_ratio | 15 | 5 | 15 |
| fs.file-max | 2000000 | 1000000 | 3000000 |
| net.netfilter.nf_conntrack_max | не нужен | не нужен | 2000000 |
| tcp_congestion_control | bbr | cubic | bbr |
Безопасность через sysctl
Кстати, sysctl — это не только про производительность. Это ещё и отличный инструмент для harden'инга, то есть усиления безопасности системы! Вот минимальный набор, который мы рекомендуем для любого продакшн-сервера:
# /etc/sysctl.d/40-security.conf
# Защита от SYN-флуда
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 3
# Отключаем ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# Логи spoofed-пакетов
net.ipv4.conf.all.log_martians = 1
# Reverse Path Filter
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Игнорируем broadcast pings
net.ipv4.icmp_echo_ignore_broadcasts = 1
# ASLR на максимум
kernel.randomize_va_space = 2
# Защита от core-dump привилегированных процессов
fs.suid_dumpable = 0
# Запрет dmesg для непривилегированных
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
Файловые дескрипторы и inotify
Столкнулись с тем, что веб-серверы, докер-демоны или наблюдатели за файлами вдруг «затыкаются»? Часто причина кроется в лимитах файловых дескрипторов. Мы их просто поднимаем:
# /etc/sysctl.d/55-files.conf
fs.file-max = 2000000
fs.nr_open = 2000000
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 512
fs.inotify.max_queued_events = 32768
Без увеличения inotify.max_user_watches на активной файловой системе с большим количеством файлов (npm node_modules, git-репозитории) редакторы VS Code, WebStorm и файловые синхронизаторы начинают пропускать изменения.
Кейс: ускорение nginx-прокси для видеостриминга
Позвольте рассказать об одном из наших реальных кейсов. В марте 2025 года к нам обратились с интересной задачей: нужно было настроить nginx-прокси, который стоял перед огромным кластером видеокодирования. Что там было по «железу»? Сервер Dell PowerEdge R750, внутри — два процессора Xeon Platinum 8280, 128 ГБ оперативной памяти и, конечно, шустрая сеть 40G Mellanox ConnectX-5. Всё это работало в дата-центре МТС. А какая была нагрузка? Представьте: 12 000 одновременных клиентских соединений! И в пике сервер должен был отдавать до 8 гигабит в секунду исходящего трафика.
Что мы увидели после установки дефолтной Ubuntu 24.04? Потолок был на уровне 6.2 Gbps, и при этом наблюдались довольно странные задержки при отдаче данных. Это нас, конечно, не устраивало. Мы начали действовать поэтапно: сперва включили `rmem/wmem buffers`, затем BBR вместе с `fq`. Также подняли `somaxconn` до 65535 и расширили `ip_local_port_range` до 2000-65535. Важный момент: каждый наш шаг тщательно измерялся при помощи `wrk` и `flent`. И каков же итог? Прирост оказался просто потрясающим: с изначальных 6.2 Gbps мы вышли на стабильные 9.8 Gbps! Среднее время ответа драматически упало — со 120 мс до всего лишь 45 мс. Причём львиную долю этого прироста, целых 2 Gbps, нам дал один лишь BBR. Все работы, включая полноценные нагрузочные тесты, заняли у нас всего два дня. Стоимость? 32 000 рублей.
Чего НЕ стоит делать
На нашей практике мы, к сожалению, регулярно сталкиваемся с тем, что называется «вредными советами». Таких вот «экспертов» хватает:
- net.ipv4.tcp_tw_recycle = 1. Этот параметр удалён из ядра в 4.12. Если видите в конфиге — удалите, иначе приложение может не запуститься.
- kernel.sched_min_granularity_ns и sched_wakeup_granularity_ns. На современных CFS эти параметры трогать не нужно. Дефолты оптимальны.
- vm.swappiness = 0. Полное отключение swap — прямой путь к OOM при пиках памяти.
- net.ipv4.tcp_sack = 0. SACK нужен для нормальной работы TCP на современных сетях. Отключают только параноики.
- Слепо увеличивать conntrack_max. Без контроля за hashsize приведёт к деградации производительности netfilter.
Настроим sysctl под вашу нагрузку с замерами
Что мы делаем? Мы тщательно проводим нагрузочное тестирование, чтобы потом подобрать идеальные параметры ядра именно под ваши конкретные приложения — будь то nginx, PostgreSQL, HAProxy или K8s-узел. И, конечно, мы всегда документируем каждый шаг: что именно мы поменяли и, главное, зачем. Обычно на один сервер у нас уходит 2-5 рабочих дней.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — частые вопросы по sysctl-тюнингу
- Нужен ли sysctl-тюнинг современному Linux?
- Для офисной нагрузки дефолты Ubuntu 24.04 / RHEL 9 адекватны. Тюнинг — для веб-серверов от 1000 RPS, БД, прокси.
- Что такое vm.swappiness и куда его ставить?
- 1-10 для БД, 10-30 для обычных серверов. 60 — для десктопов.
- Стоит ли включать BBR вместо cubic?
- Да, на веб-серверах и прокси обычно +20-50% к скорости отдачи.
- Как применить изменения без ребута?
- sudo sysctl -p /etc/sysctl.d/99-tuning.conf — большинство параметров применяются сразу.
- Какой net.core.somaxconn ставить?
- Для nginx/HAProxy с высокой нагрузкой — 65535, с синхронной настройкой backlog в конфиге сервиса.
