Настройка ядра Linux (sysctl) для высоконагруженных серверов
Дефолтные параметры ядра Linux — компромисс между совместимостью и производительностью. На сервере с 10k+ одновременных соединений или высоким UDP-трафиком они превращаются в узкое место: приложение получает EMFILE, сокеты зависают в TIME_WAIT, пакеты теряются. Мы уже не раз сталкивались с этим на проектах: когда метрики показывают просадку, а CPU и RAM свободны — причина почти всегда в sysctl. За более чем 5 лет тюнинга ядра мы собрали профили для webserver, БД, балансировщика. В этой статье — готовые конфиги и практика, без теории. Наш опыт: на одном проекте с 50k RPS простое увеличение somaxconn и включение BBR снизило latency на 30%.
Почему дефолтные настройки ядра — узкое место?
Ядро Linux из коробки настроено на универсальность: moderate backlog, консервативный TCP, малые буферы. На highload это превращается в:
- Переполнение очереди соединений. Каждый listen-сокет имеет backlog. При burst-трафике очередь переполняется — SYN-пакеты дропаются. Дефолтный
net.core.somaxconn = 4096давит уже на 5k RPS. Мы ставим 65535. - TIME_WAIT и нехватка эфемерных портов. Каждое закрытое TCP-соединение держится 2*MSL (60 с). При 10k запросов/сек — 600k сокетов в TIME_WAIT. Пул портов 32768–60999 (28k) исчерпывается за секунду. Решение: расширяем диапазон, включаем
tcp_tw_reuse, уменьшаемtcp_fin_timeout. - Малые буферы приёма/передачи. Дефолтные
rmem_default=87380иwmem_default=16384тормозят high-latency соединения (CDN, межрегион). Для потоковых серверов это критично.
# /etc/sysctl.d/99-network.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_tw_buckets = 1440000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216 Как BBR и буферы выжимают максимум из сети?
BBR (Bottleneck Bandwidth and RTT) от Google — алгоритм контроля перегрузки, который работает на основе измерений, а не потерь. На WAN-каналах с высокой задержкой (100+ ms) BBR даёт прирост скорости до 40% по сравнению с CUBIC, а в некоторых сценариях BBR лучше CUBIC в 1.5–2 раза по пропускной способности. Включается парой строк:
net.core.default_qdisc = fq net.ipv4.tcp_congestion_control = bbr Поддержку проверяем через sysctl net.ipv4.tcp_available_congestion_control — должен быть bbr cubic reno. Доступен с ядра 4.9.
Буферы: для соединений с high bandwidth-delay product (например, 100 Mbps × 200 ms = 2.5 MB) дефолтных буферов не хватает. Увеличение tcp_rmem до 16 MB позволяет полностью заполнить канал и не терять пропускную способность.
| Алгоритм | Механизм | Задержка | Пропускная способность | Типичное применение |
|---|---|---|---|---|
| CUBIC | Потери пакетов | Средняя | Хорошая на LAN | Дефолт, стабильность |
| BBR | Измерение RTT/BW | Низкая | До 40% выше на WAN | CDN, межрегион, нестабильные каналы |
| Reno | Потери пакетов | Высокая | Низкая | Legacy совместимость |
Как не упереться в лимит файловых дескрипторов?
Вторая частая причина деградации — нехватка fd. Nginx с 65536 worker_connections потребляет 131072 fd (каждый connection — сокет и файловый дескриптор). Дефолт fs.file-max = 524288 быстро исчерпывается. Настраиваем:
# /etc/sysctl.d/99-fs.conf fs.file-max = 2097152 fs.nr_open = 1048576 Важно: fs.nr_open — максимальный лимит на один процесс. Для nginx также проверьте LimitNOFILE в systemd-юните (обычно LimitNOFILE=65536). Проверить текущий лимит: cat /proc/$(pidof nginx)/limits | grep "Open files". Использование: cat /proc/sys/fs/file-nr (первое число — используется, третье — максимум). Проверьте текущие лимиты процесса: cat /proc/<PID>/limits | grep 'Max open files'. Также смотрите общее использование системы: cat /proc/sys/fs/file-nr. Если приближается к file-max, нужно увеличивать.
Память: swappiness, dirty ratio, overcommit
# /etc/sysctl.d/99-memory.conf (опционально, входит в полный профиль)
vm.swappiness = 10
vm.dirty_ratio = 20
vm.dirty_background_ratio = 5
vm.overcommit_memory = 1
vm.overcommit_ratio = 50 -
vm.swappiness = 10— ядро свопит только при крайней необходимости. Для Redis/Memcached ставят 0 или 1 (но 0 не отключает своп полностью). -
vm.dirty_ratio = 20+vm.dirty_background_ratio = 5: при 5% грязных страниц ядро начинает фоновую запись, при 20% блокирует write(). Для NVMe можно снизитьdirty_background_ratioдо 3. -
vm.overcommit_memory = 1+vm.overcommit_ratio = 50— разрешаем overcommit на 50% от RAM. Нужно для Redis (fork при bgsave) и Java с большими heap.
Что входит в работу по тюнингу ядра
- Аудит текущих параметров: сбор
sysctl -a,ss -s,cat /proc/sys/fs/file-nr, профилирование нагрузки (RPS, типы соединений). - Профилирование под нагрузку: используем wrk, iperf3, pgbench для точного подбора.
- Подготовка профиля: детальный конфиг с обоснованием каждого параметра под ваш workload.
- Применение и мониторинг: поэтапное внедрение с контролем метрик (latency, throughput, error rate).
- Документация: описание всех изменений, почему и как откатить.
- Гарантия: 3 месяца пост-релизной поддержки — если профиль не даёт ожидаемого прироста, доводим бесплатно.
| Масштаб тюнинга | Срок | Типичные результаты |
|---|---|---|
| Базовый (веб-сервер) | 4–8 часов | Устранение TIME_WAIT, увеличение max connections на 30% |
| Углублённый (с профилированием) | 1–3 дня | Снижение latency на 20–40%, рост throughput |
| Комплексный (sysctl + HW + scheduler) | 2–5 дней | Максимальная загрузка железа, оптимальный cost/performance |
Стоимость тюнинга рассчитывается индивидуально, но окупаемость обычно менее 3 месяцев за счёт роста производительности. Экономия на оборудовании может достигать 30%. Закажите консультацию — оценим ваш проект.
Процесс работы
- Аналитика — аудит текущих sysctl, выявление узких мест (TIME_WAIT, fd, буферы).
- Проектирование — подбор профиля под тип нагрузки (веб, БД, streaming).
- Реализация — применение через
/etc/sysctl.d/, тестирование в staging. - Тестирование под нагрузкой — wrk, iperf3, сравнение метрик.
- Деплой на production с мониторингом (Prometheus + Grafana).
Наша команда — 6 лет опыта в DevOps, 80+ проектов по оптимизации. Результат гарантируем. Свяжитесь с нами, чтобы получить детальный анализ вашей системы.
Применить все конфиги можно командой sysctl --system, а проверить конкретный параметр — sysctl net.ipv4.tcp_tw_reuse. Перед изменениями снимите слепок: sysctl -a > /tmp/sysctl-before.txt.
Полный production-профиль:
# /etc/sysctl.d/99-highload.conf
# Сеть — TCP
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_slow_start_after_idle = 0
# Буферы
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# BBR
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# Файловые дескрипторы
fs.file-max = 2097152
# Память
vm.swappiness = 10
vm.dirty_ratio = 20
vm.dirty_background_ratio = 5
Подробнее о BBR на Wikipedia.







