Налаштування ядра 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 (кожне з'єднання — сокет і файловий дескриптор). Дефолт 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.







