Тюнинг ядра Linux для высоконагруженных серверов

Зачем тюнить ядро: дефолты не для production

Компания «НагрузТест» — SaaS-платформа для нагрузочного тестирования. Сервер: 64 CPU, 256 GB RAM, 10G NIC. При 50,000 одновременных соединений начинались потери пакетов и рост latency. Дефолтные настройки Linux рассчитаны на десктоп с 4 ГБ RAM, не на сервер с четвертью терабайта.

# Типичные дефолты vs production-значения
sysctl net.core.somaxconn          # 4096 (нужно 65535)
sysctl net.ipv4.tcp_max_syn_backlog # 1024 (нужно 65535)
sysctl net.core.netdev_max_backlog  # 1000 (нужно 50000)
sysctl vm.swappiness                # 60 (нужно 1-10)
cat /proc/sys/fs/file-max           # 65535 (нужно 2000000)

Три области тюнинга с максимальным эффектом:

  1. Сеть (TCP/IP стек) — буферы, backlog, TIME_WAIT
  2. Дисковый I/O — планировщик, readahead, dirty pages
  3. Память — hugepages, swappiness, overcommit, NUMA

Сетевой стек: TCP-буферы и backlog

# /etc/sysctl.d/90-network-tuning.conf

# === BACKLOG И ОЧЕРЕДИ ===
net.core.somaxconn = 65535              # Max listen() backlog
net.ipv4.tcp_max_syn_backlog = 65535    # SYN queue size
net.core.netdev_max_backlog = 50000     # NIC ring buffer queue

# === TCP БУФЕРЫ ===
net.core.rmem_max = 16777216            # Max receive buffer (16MB)
net.core.wmem_max = 16777216            # Max send buffer (16MB)
net.ipv4.tcp_rmem = 4096 87380 16777216 # min default max (receive)
net.ipv4.tcp_wmem = 4096 65536 16777216 # min default max (send)

# === TIME_WAIT ===
net.ipv4.tcp_tw_reuse = 1              # Reuse TIME_WAIT sockets
net.ipv4.tcp_fin_timeout = 15          # FIN-WAIT-2 timeout (default 60)
net.ipv4.tcp_max_tw_buckets = 200000   # Max TIME_WAIT sockets

# === KEEPALIVE ===
net.ipv4.tcp_keepalive_time = 300      # Start probes after 5min (default 7200)
net.ipv4.tcp_keepalive_intvl = 30      # Probe interval
net.ipv4.tcp_keepalive_probes = 5      # Probes before drop

# === CONGESTION CONTROL ===
net.ipv4.tcp_congestion_control = bbr  # BBR вместо cubic
net.core.default_qdisc = fq           # Fair Queue для BBR

# === ФАЙЛОВЫЕ ДЕСКРИПТОРЫ ===
fs.file-max = 2000000                  # Max open files system-wide
fs.nr_open = 2000000                   # Max open files per process
# Применение
sysctl --system

# Проверка BBR
sysctl net.ipv4.tcp_congestion_control
# net.ipv4.tcp_congestion_control = bbr
BBR: алгоритм управления перегрузкой от Google. На каналах с потерями (>0.1%) BBR даёт пропускную способность в 2-10 раз выше, чем дефолтный CUBIC. Для серверов с 10G NIC и интернет-трафиком — must have.

Дисковый I/O: планировщик и dirty pages

# /etc/sysctl.d/91-io-tuning.conf

# === DIRTY PAGES ===
# Когда ядро начинает фоновый flush на диск
vm.dirty_background_ratio = 5          # 5% RAM (default 10)
# Когда процесс блокируется до завершения flush
vm.dirty_ratio = 15                    # 15% RAM (default 20)
# Максимальное время жизни dirty page (centiseconds)
vm.dirty_expire_centisecs = 1500       # 15 sec (default 30)
vm.dirty_writeback_centisecs = 500     # Flush каждые 5 sec
# Планировщик I/O — выбор зависит от типа диска
# Для NVMe SSD: none (самый быстрый, SSD сам оптимизирует)
echo none > /sys/block/nvme0n1/queue/scheduler

# Для SATA SSD: mq-deadline
echo mq-deadline > /sys/block/sda/queue/scheduler

# Для HDD: bfq (fair queueing)
echo bfq > /sys/block/sdb/queue/scheduler

# Readahead для HDD (sequential read workloads)
blockdev --setra 4096 /dev/sdb    # 2MB readahead (default 256 = 128KB)

# Для SSD — уменьшаем readahead
blockdev --setra 256 /dev/nvme0n1  # 128KB достаточно

Результат для PostgreSQL на NVMe:

МетрикаDefaultTuned
pgbench TPS4,2006,800 (+62%)
WAL write latency0.8 ms0.3 ms
Checkpoint duration45 sec18 sec

Память: Hugepages, NUMA, swappiness

# /etc/sysctl.d/92-memory-tuning.conf

# === SWAPPINESS ===
vm.swappiness = 1                      # Почти не свопить (0 = полностью отключить)
                                        # Для БД: 1, для веб: 10

# === OVERCOMMIT ===
vm.overcommit_memory = 0               # Heuristic (default)
# Для Redis: vm.overcommit_memory = 1  (всегда разрешать)

# === HUGEPAGES (для PostgreSQL, Java, Redis) ===
# 2MB hugepages вместо 4KB standard pages
# Уменьшает TLB misses на 99% для больших рабочих наборов
# Расчёт hugepages для PostgreSQL (shared_buffers = 8GB)
# 8GB / 2MB = 4096 hugepages + запас
echo 4500 > /proc/sys/vm/nr_hugepages

# Постоянная настройка
echo "vm.nr_hugepages = 4500" >> /etc/sysctl.d/92-memory-tuning.conf

# PostgreSQL: включить hugepages
# postgresql.conf: huge_pages = on

# Transparent Hugepages (THP) — ВЫКЛЮЧИТЬ для БД!
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# THP вызывает latency spikes из-за compaction

NUMA-оптимизация для многосокетных серверов:

# Проверка NUMA-топологии
numactl --hardware
# node 0: cpus 0-31, memory 128GB
# node 1: cpus 32-63, memory 128GB

# Привязка PostgreSQL к NUMA node 0
numactl --cpunodebind=0 --membind=0 postgres

# Или через systemd:
# [Service]
# NUMAPolicy=bind
# NUMAMask=0

Итоговый чеклист и результаты

Полный sysctl-конфиг «НагрузТест» после тюнинга:

# Быстрая проверка текущих настроек
for param in net.core.somaxconn vm.swappiness net.ipv4.tcp_congestion_control \
  fs.file-max vm.dirty_ratio net.core.rmem_max; do
    echo "$param = $(sysctl -n $param)"
done
МетрикаDefault kernelTuned kernelImprovement
Max concurrent connections~20,000100,000++400%
Network throughput (10G NIC)6.2 Gbps9.4 Gbps+52%
Disk I/O (NVMe IOPS)380K620K+63%
TCP latency p992.1 ms0.4 ms-81%
PostgreSQL TPS4,2006,800+62%
Важно: Не копируйте настройки вслепую. Каждый параметр должен соответствовать вашей нагрузке. net.core.rmem_max = 16MB имеет смысл для 10G NIC, но для 100Mbps VPS это перерасход памяти. Тюните под свои бенчмарки.

Часто задаваемые вопросы

Бенчмарки до и после: wrk/vegeta для HTTP, fio для дисков, iperf3 для сети, pgbench для PostgreSQL. Записывайте baseline перед изменениями. Один параметр за раз — иначе не поймёте, что именно помогло.

Нет. BBR лучше на каналах с потерями (интернет, WAN). На локальной сети без потерь CUBIC может быть чуть эффективнее. BBR v2 (bbr2) в ядрах 6.x решает проблему fairness. Для серверов с интернет-трафиком BBR — рекомендация.

THP автоматически объединяет 4KB страницы в 2MB. Процесс compaction (дефрагментация памяти для создания hugepage) вызывает непредсказуемые паузы до 100мс. Для баз данных (PostgreSQL, Redis, MongoDB) это неприемлемо. Используйте static hugepages вместо THP.

Нет, swappiness=0 означает 'свопить только при критической нехватке памяти'. Ядро всё равно может использовать swap. Для полного отключения: swapoff -a. Но для production серверов рекомендуется swappiness=1 и иметь swap — лучше замедлиться, чем OOM kill.

Да, особенно сетевой стек. Cloud VM получают те же дефолтные sysctl. BBR, TCP буферы, somaxconn — всё применимо. Планировщик I/O менее важен (облачные диски виртуальные). Hugepages работают, но зависят от типа инстанса.

Нужна помощь с внедрением?

Настроим, оптимизируем и возьмём на поддержку вашу инфраструктуру. 15+ лет опыта, 8 серверов Dell Xeon в дата-центре МТС.

📞 Связаться с нами

Комментарии 0

Оставить комментарий

5 + 3 =