Linux kernel — tuning wydajności systemu dla serwerów produkcyjnych
Opublikowano: 10 kwietnia 2026 · Kategoria: VPS
Domyślna konfiguracja kernela Linux jest celowo konserwatywna — działa na desktopach, laptopach, serwerach i urządzeniach embedded. Serwer produkcyjny ma zupełnie inne priorytety: maksymalna przepustowość sieciowa, niskie latencje I/O, brak paginacji, obsługa dziesiątek tysięcy jednoczesnych połączeń. Ten artykuł pokazuje jakie parametry zmienić i dlaczego — z uwzględnieniem różnicy między serwerami baz danych, webserwerami i VPS.
sysctl.conf — parametry sieci i pamięci
# Sprawdź obecne wartości sysctl -a | grep net.core sysctl net.ipv4.tcp_fin_timeout # Zmień bez restartu (tymczasowo) sysctl -w net.core.somaxconn=65535 # /etc/sysctl.d/99-server-tuning.conf — trwała konfiguracja # ===================================================== # SIEC — Web server / API (Nginx, Node.js, PHP-FPM) # ===================================================== # Kolejka połączeń przychodzących net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.core.netdev_max_backlog = 250000 # Bufor sieciowy (dla duzej przepustowosci) net.core.rmem_max = 134217728 net.core.wmem_max = 134217728 net.ipv4.tcp_rmem = 4096 87380 134217728 net.ipv4.tcp_wmem = 4096 65536 134217728 # Szybsze zamykanie polaczen (recykling portow) net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 net.ipv4.ip_local_port_range = 1024 65535 # TIME_WAIT — wazne dla serwerow z duza iloscia polaczen net.ipv4.tcp_max_tw_buckets = 1440000 # ===================================================== # PAMIEC — Serwery aplikacyjne # ===================================================== # Unikaj swapu dla serwerow aplikacyjnych (0 = swap tylko przy krytycznym braku RAM) vm.swappiness = 10 # Dirty pages — jak czesto zapisywac brudne strony na dysk vm.dirty_ratio = 60 vm.dirty_background_ratio = 5 # Inotify — dla Node.js/React dev i watcherow plikow fs.inotify.max_user_watches = 524288 fs.inotify.max_user_instances = 8192 # Deskryptory plikow — globalne dla systemu fs.file-max = 2097152 # Zaladuj konfiguracje bez restartu sudo sysctl -p /etc/sysctl.d/99-server-tuning.conf
ulimit i limits.conf — limity zasobów procesów
# Sprawdź aktualne limity ulimit -a # limity biezacej sesji ulimit -n # open files limit cat /proc/$$/limits # limity biezacego procesu # Sprawdz limity konkretnego procesu (np. Nginx worker) cat /proc/$(pgrep -x nginx | head -1)/limits | grep "open files" # /etc/security/limits.conf — limity dla uzytkownikow (PAM) # ======================================================== # Nginx www-data soft nofile 65535 www-data hard nofile 65535 # PostgreSQL postgres soft nofile 65535 postgres hard nofile 65535 postgres soft nproc 65535 postgres hard nproc 65535 # Wszsycy uzytkownicy (nie zalecane, lepiej per-user) * soft nofile 65535 * hard nofile 65535 # /etc/pam.d/common-session musi miec: # session required pam_limits.so # (zwykle jest domyslnie) # Dla systemd services — PREFEROWANE dla daemonow # /etc/systemd/system/nginx.service.d/override.conf # [Service] # LimitNOFILE=65535 # LimitNPROC=65535 # Zastosuj bez restartu (dla systemd) sudo systemctl daemon-reload sudo systemctl restart nginx # Weryfikacja po zmianie cat /proc/$(pgrep -x nginx | head -1)/limits | grep "open files" # Powinna pokazac limit=65535
Transparent Hugepages — kiedy wyłączyć
# Sprawdz aktualne ustawienie cat /sys/kernel/mm/transparent_hugepage/enabled # [always] madvise never <-- aktywne (always) # Wyniki: [always] madvise never = zawsze uzywaj THP # always [madvise] never = tylko gdy aplikacja pyta (safe) # always madvise [never] = wylaczone # WYŁĄCZ dla baz danych (Redis, PostgreSQL, MySQL, MongoDB) echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag # Trwałe wyłączenie przez GRUB # /etc/default/grub: # GRUB_CMDLINE_LINUX="... transparent_hugepage=never" sudo update-grub # Alternatywa: madvise (zalecanew dla mieszanych workloadow) echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/enabled # Sprawdz czy Redis narzeka na THP (tipowy komunikat): # redis-cli info server | grep thp # WARNING: You have Transparent Huge Pages (THP) support enabled in your kernel.
CPU Governor — tryb wydajności procesora
# Sprawdz dostepne governory i aktualny cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor # Governory: # performance — max czestotliwosc przez caly czas (serwer produkcyjny) # powersave — oszczednosc energii (laptop, nieprodukcja) # ondemand — skaluje po potrzebie (legacy, wolna reakcja) # schedutil — skaluje zgodnie z CFS scheduler (nowoczesny default) # conservative — ostrożniejsze skalowanie niz ondemand # Ustaw performance dla wszystkich rdzeni (tymczasowo) for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance | sudo tee $cpu done # Trwale przez cpufrequtils sudo apt install cpufrequtils -y echo 'GOVERNOR="performance"' | sudo tee /etc/default/cpufrequtils sudo systemctl restart cpufrequtils # Na serwerach Intel sprawdz tez: # /sys/devices/system/cpu/intel_pstate/no_turbo echo 0 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo # wlacz turbo boost
I/O Scheduler — optimalizacja dla SSD i HDD
| Scheduler | Najlepszy dla | Latencja | Przepustowość |
|---|---|---|---|
| none (noop) | NVMe SSD, wirtualne maszyny | Bardzo niska | Bardzo wysoka |
| mq-deadline | SSD, bazy danych (MySQL/Postgres) | Niska | Wysoka |
| bfq (Budget Fair Queueing) | HDD, mixed workloads, interaktywne | Przewidywalna | Dobra |
| kyber | SSD multi-queue, niska latencja | Bardzo niska | Wysoka |
# Sprawdz scheduler i typ dysku
cat /sys/block/sda/queue/scheduler
lsblk -d -o NAME,ROTA # ROTA=0 to SSD/NVMe, ROTA=1 to HDD
# Ustaw scheduler dla SSD/NVMe (tymczasowo)
echo none | sudo tee /sys/block/nvme0n1/queue/scheduler
echo mq-deadline | sudo tee /sys/block/sda/queue/scheduler # SSD SATA
# Trwale przez udev rules (zalecane)
# /etc/udev/rules.d/60-io-scheduler.rules:
# ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
# ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
# ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none"
sudo udevadm control --reload-rules
sudo udevadm trigger --type=devices --action=change IRQ Affinity i NUMA awareness
# Sprawdz topologie NUMA (multi-socket serwery) numactl --hardware # available: 2 nodes (0-1) # node 0 cpus: 0 1 2 3 4 5 6 7 # node 1 cpus: 8 9 10 11 12 13 14 15 # Uruchom aplikacje na okreslonym NUMA node (lokalnosc pamieci) numactl --cpunodebind=0 --membind=0 nginx numactl --cpunodebind=1 --membind=1 postgres # IRQ affinity — przypnij przerwania sieciowe do konkretnych rdzeni # Sprawdz aktualne przerwania cat /proc/interrupts | grep -E "eth|ens|enp" # Automatyczne balansowanie IRQ przez irqbalance (zalecane dla wiekszosci serwerow) sudo apt install irqbalance -y sudo systemctl enable --now irqbalance # Reczne przypinanie IRQ do rdzeni (zaawansowane — multi-queue NIC) # Sprawdz queues karty sieciowej: ls /sys/class/net/eth0/queues/ ethtool -l eth0 # pokaz combined queues # Ustaw RSS (Receive Side Scaling) — rozprasza ruch na wiele CPU ethtool -X eth0 equal 8 # 8 CPU dla RX queues