← Zpět na všechny články blogu

Jak na tuning PHP-FPM?

David Janík
David Janík 28. 4. 2021 - 10 min. čtení
Blog

Článek vás provede nastavením PHP na straně serveru. Vysvětlíme, co jednotlivé direktivy znamenají, jaký mají smysl a vypočítáme, jak je správně nastavit.

Nejdříve se podíváme, kde tyto hodnoty najdete přímo na serveru a v našem VPS Centru.

Začneme u konkrétní domény. Po přihlášení do VPS Centra vyberete konkrétní nastavení domény a najdete sekci Nastavení PHP.

Kde si vysvětlíme hlavně tyto hodnoty:

VPS Centrum

Vyzkoušejte zdarma naši aplikaci pro správu serveru a domén. Budete si připadat jako zkušený administrátor.

  • pm = ondemand
  • pm.max_children = 20
  • pm.start_servers = 2
  • pm.min_spare_servers = 1
  • pm.max_spare_servers = 3
  • pm.process_idle_timeout = 30s
  • pm.max_requests = 500

Případně se můžete připojit na SSH a konfigurační soubor ke každé doméně najdete v
> /etc/php5/fpm/pool.d/php-tuning.cz.conf

Ještě si ukážeme, kde najdeme šablonu podle které se vytváří PHP konfigurace pro každou nově založenou doménu. Jakmile najdete své ideální hodnoty, tak je můžete upravit právě v této šabloně a nemusíte je pak manuálně upravovat u každé nové domény.

Ve VPS Centru běžte do sekce Správa serveru > Web & FTP, kde najdete šablony konfiguračních souborů pro nové domény. 

Případně na SSH /etc/php5/fpm/default.conf

Pokud v šabloně cokoliv změníte, tak se každá nová doména založí právě s těmito hodnotami.

Tuning PHP-FPM

Nejdříve musíme vědět, co které hodnoty znamenají, abychom je zvládli přizpůsobit konkrétnímu projektu.

Freelo - Nástroj na řízení úkolů a projektů

Přidej se, pozvi svůj tým a klienty, rozděl práci a sleduj, jak se úkoly dají do pohybu.

Hodnota pm

Pomocí této hodnoty můžete nastavit, jak se tento process manager bude chovat ohledně PHP procesů a RAM. Celkově se musí vybírat na základě očekávaného trafficu. Jsou 3 nastavení, ze kterých si můžeme vybrat:

  • pm = dynamic 
  • pm = ondemand
  • pm = static

Dynamic

Je v praxi nejběžnější. Nastavíte 4 parametry a process manager pak dynamicky vytváří a zabíjí procesy podle zátěže. Musíte nastavit tyto parametry:

  • pm.max_children = počet podřízených procesů, které se mají vytvořit, když je pm nastaven na statický, a maximální počet podřízených procesů, které mají být vytvořeny, když je pm nastaven na dynamický.
  • pm.start_server = počet procesů při startu fpm 
  • pm.min_spare_servers = minimální počet procesů v ‚idle‘ stavu
  • pm.max_spare_server = maximální počet procesů v ‚idle‘ stavu

Všeobecně je pm.max_children individuální a počítá se podle průměrné velikosti PHP procesů. Velikost procesů zjistíte následným příkazem:

~# ps -ylC 'php-fpm7.4' --sort:rss

S UID PID PPID C PRI NI RS SZ WCHAN TTY TIME CMD

S 33 22657 28210 0 80 0 10744 75603 - ? 00:00:00 php-fpm7.4

S 33 22656 28210 0 80 0 10752 75603 - ? 00:00:00 php-fpm7.4

S 0 28210 1 0 80 0 19528 75612 do_epo ? 00:26:55 php-fpm7.4

S 33 22356 28210 2 80 0 60084 95632 - ? 00:00:00 php-fpm7.4

S 33 22431 28210 3 80 0 66296 78561 - ? 00:00:00 php-fpm7.4

S 33 19168 28210 2 80 0 66660 95835 x64_sy ? 00:00:07 php-fpm7.4

S 33 20314 28210 2 80 0 66660 95819 x64_sy ? 00:00:06 php-fpm7.4

S 33 20334 28210 2 80 0 66768 95857 - ? 00:00:04 php-fpm7.4

D 33 22488 28210 2 80 0 67864 96948 - ? 00:00:00 php-fpm7.4

S 33 22261 28210 3 80 0 68288 96461 - ? 00:00:01 php-fpm7.4

S 33 21139 28210 4 80 0 68404 96219 x64_sy ? 00:00:06 php-fpm7.4

S 33 19667 28210 2 80 0 68640 96257 - ? 00:00:07 php-fpm7.4

S 33 18553 28210 2 80 0 70028 95800 - ? 00:00:08 php-fpm7.4

S 33 22371 28210 3 80 0 70752 96969 - ? 00:00:00 php-fpm7.4

S 33 18382 28210 2 80 0 73440 96265 - ? 00:00:10 php-fpm7.4

S 33 17408 28210 2 80 0 73576 95764 - ? 00:00:12 php-fpm7.4

S 33 19627 28210 2 80 0 75704 96908 - ? 00:00:06 php-fpm7.4

S 33 18599 28210 12 80 0 80616 97331 - ? 00:00:47 php-fpm7.4

S 33 20298 28210 4 80 0 83424 97293 x64_sy ? 00:00:09 php-fpm7.4

S 33 17651 28210 7 80 0 84400 97364 - ? 00:00:34 php-fpm7.4

S 33 18897 28210 3 80 0 88308 99240 - ? 00:00:13 php-fpm7.4

S 33 20097 28210 3 80 0 88448 98543 - ? 00:00:08 php-fpm7.4

S 33 18650 28210 4 80 0 97668 101891 - ? 00:00:15 php-fpm7.4

Tady vidíte, že procesy mají velikost od 10 do 100MB. Počítejme s průměrem tedy kolem 65 MB. Do rovnice musíme ještě vzít v potaz další SW, který je na serveru nainstalovaný, a kolik si bere RAM. Např. MySQL, Redis, Kibana, Elasticsearch atd.

Počítejme třeba s tím, že máme server s 2x CPU 4 core, 8 GB RAM a průměrná velikost PHP procesu je 65 MB. Pomocí Muninu nebo třeba Sysinfa jsme zjistili, že veškeré ostatní aplikace na serveru zabírají 4 GB RAM a zbývá tedy 4096 MB.

4096 / 65 = 63 -10% = 57 pm.max_children. vždy je dobré konečný výsledek zmenšit ještě o 10%, aby tam byla rezerva.

A ostatní hodnoty můžete vypočítat tímto způsobem:

pm.start_servers = 32 (protože 4x počet jader (8))

pm.min_spare_servers = 16 (2x počet jader (8))

pm.max_spare_servers = 32 (4x počet jader (8))

Static

Nastavení Static se využívá hlavně pro servery, kde se očekává velký provoz. Jak název napovídá, tak nadefinujete pm.max_chlidren a tento počet procesů bude neustále běžet a připraven vyřizovat požadavky. Využijete tedy serverové prostředky na maximum.

Stačí nastavit pouze jednu hodnotu a nic dalšího nastavovat už nemusíte. Je potřeba si být jistý, kolik paměti si můžete dovolit takto využít. Když si vezmeme příklad, který jsme počítali výše, tak bychom měli 57 procesů, které by aktivně čekali na požadavky, které by mohly ihned vyřizovat. 

Místo toho, aby se čekalo než je process manager vytvoří a pak je zase po nastaveném čase zabíjel. Tím se ušetří paměť a server bude vždy “ve střehu”.

Ondemand

Jedná se o plně dynamickou variantu, která při startu neinicializuje žádné workery. Stačí nastavit pouze 2 parametry, kde timeout určí, za jak dlouho bude worker ukončen pokud nic neprovádí a samozřejmě pm.max_children.

Výhoda nastavení ondemand je, že okamžitě uvolňuje paměť. Díky tomu není overhead tak velký, a nemusí se řešit. Lépe se škáluje monitoring a jakmile se rychle začne zaplňovat paměť, tak můžete zbystřit a podniknout příslušné kroky.

Poslední věc, kterou k ondemand ještě potřebujete vědět je hodnota pm.max_request. Obecně se uvádí, že nejlepší a nejvyužívanější je hodnota 200. To řekne, že jeden worker vyřídí 200 requestů a pak se ukončí a spustí se nový. 

Pokud byste měli aplikaci, která těch requestů vytváří víc, je vhodné max. počet požadavků snížit. To stejně by platilo pokud by server byl pod velkou zátěží. Tady neexistuje jednoduchá rovnice nebo přesný tip, a každý programátor / správce si musí správně otestovat a vyzkoušet, které hodnoty jsou pro jeho aplikaci nejvhodnější.

Doporučujeme ještě přečíst oficiální manuál PHP, kde máte veškeré hodnoty popsané.

Memory limit

PHP memory_limit je nastavení pro PHP skript,který říka kolik paměti může daný skript max. využít. Stejně jako je rychlostní limit dálnice pro motorové vozidlo. Například, i když může být limit paměti PHP nastaven vysoko na 1 GB, neznamená to, že se skripty nahromadí, aby tento 1GB využili.

V PHP dokumentaci vypadá vysvětlení takto:

“Tím se nastaví maximální velikost paměti v bajtech, kterou může skript přidělit. To pomáhá zabránit špatně napsaným skriptům, které by pohltily veškerou dostupnou paměť na serveru.”

Na rozdíl od nastavení MySQL key_buffer_size nebo innodb_buffer_pool nastavení PHP memory_limit není úložný prostor, kde se shromažďuje nebo roste více skriptů PHP. Spíše jde o limit na skript. PHP memory_limit je maximální velikost paměti serveru, kterou může jeden skript PHP spotřebovat. 

Při zablokování vypadá výsledný chybový výstup asi takto:

Fatal error: Allowed memory size of x bytes exhausted (tried to allocate x bytes) in /path/to/php/script

nebo

PHP Fatal error: Out of memory (allocated x) (tried to allocate x bytes) in /path/to/php/script

Pokud jsou například požadovány dva nebo více skriptů současně, každý je zcela nezávislý na druhém. Nesdílejí nastavení memory_limit. Pamatujte, že PHP není navržen pro multithreading. Pokud tedy pět (5) skriptů PHP současně používá každý po 100 MB, dosáhlo by to celkem 500 MB využití paměti PHP a memory_limit 128 MB by nebyl aktivován.

Naštěstí nastavení PHP memory_limit zablokuje neefektivní kód, který vás poté v logu upozorní na optimalizaci kódu. Dokud to nebude opraveno, možná budete chtít dočasně zvýšit PHP memory_limit, abyste zabránili tomu, aby vaše webová aplikace stala nepoužitelnou kvůli chybám paměti PHP.

Pokud na svém serveru nemáte k dispozici paměť, budete někdy čelit rozhodování, zda zvýšit PHP memory_limit tak, aby splňoval požadavky skriptů, nebo optimalizovat váš kód. 

Nejlepší by bylo, kdybyste vždy upřednostňovali optimalizaci. Můžete také zvýšit limit paměti PHP pro konkrétní webové stránky. Můžete dokonce nastavit limit pro konkrétní scriptname.php. Například pomocí ini_set („memory_limit“, „256 MB“).

Jinak PHP memory_limit nastavíte v konfiguračním souboru, jak jsme si ukazovali i další PHP hodnoty. Případně se můžete připojit na SSH a konfigurační soubor ke každé doméně najdete v
> /etc/php5/fpm/pool.d/php-tuning.cz.conf

Opcache

OPcache je rozšíření PHP, které zlepšuje výkon PHP tím, že ukládá předkompilovaný bytecode skriptů do sdílené paměti, čímž odstraňuje potřebu PHP načítat a analyzovat skripty na každý požadavek. Rozšíření je integrováno pro PHP 5.5+.

Pokud chcete zlepšit výkon PHP, prvním krokem by mělo být použití PHP 7+, které je dvakrát rychlejší než PHP 5. V každém případě použití OPcache zrychlí skripty až trojnásobně.

Jak opcache optimalizovat?

V našem VPS Centru je už opcache aktivovaný a najdete jej na konci konfiguračního souboru. Ovšem jeho konfiguraci si můžete upravit podle vašich potřeb.

opcache.revalidate_freq = 10

(default „2“) Jak často (v sekundách) kontrolovat timestamps ohledně změn alokace paměťového uložiště.

 („1“ ) Znamená, validovat jednou za sekundu ale pouze jeden požadavek.

(„0“) Znamená vždy ověřit. 

opcache.fast_shutdown = 1

(default „0“) Pokud je povoleno, použije se pro sekvenci rychlého vypnutí. Ta sice neuvolní každý přidělený blog, ale umožní správci paměti Zend Engine pracovat efektivněji.

opcache.file_update_protection = 0

(default „2“) Zabraňuje ukládání do mezipaměti souborům, které jsou menší než uvedený počet sekund. To zabrání cachování neúplně aktualizovaných souborů.

Může se hodit:

Shrnutí

Pokud jde o PHP-FPM, jakmile začnete obsluhovat vysoký provoz, může pm = ondemand a dynamic omezit propustnost kvůli vlastní režii. Poznejte svůj systém a nastavte procesy PHP-FPM tak, aby odpovídaly maximální kapacitě vašeho serveru. 

Začněte s pm.max_children nastavenou na základě maximálního využití pm dynamic nebo ondemand a poté se přesuňte do bodu, kde můžete zpracovávat paměť a CPU, aniž byste byli ochromeni. 

Všimnete si, že s pm static udržíte vše v paměti, dopravní špičky v průběhu času nevytíží tolik CPU a zatížení serveru s průměry CPU loadu budou menší. Průměrná velikost vašeho procesu PHP-FPM se bude lišit podle webového serveru, a proto jsou oblíbenější automatičtější správci procesů – dynamic a ondemand.

Máme server:

  • 8 GB RAM
  • 2x CPU 4 core
  • Ostatní aplikace vyžadují 4 GB operační paměti

Nastavení pro pm = Static

  • pm.max_children 57 ( 4096MB/65MB = 63 – 10% = 57)

Nastavení pro pm = Dynamic

  • pm.max_childer = 57 
  • pm.start_servers = 32 (protože 4x počet jader (8))
  • pm.min_spare_servers = 16 (2x počet jader (8))
  • pm.max_spare_servers = 32 (4x počet jader (8))

Nastavení pro pm = ondemand

  • pm.max_children = 57
  • pm.process_idle timeout = 10s
  • pm.max_requests = 200

Máte zajímavé tipy nebo vlastní vychytávky? Napište nám je, ať můžeme článek pravidelně aktualizovat

Zůstaňte s námi v kontaktu

Jednou za měsíc posíláme souhrn novinek. Nemusíte se bát, spam neposíláme a odhlásit se můžete kdykoliv...

Karel Dytrych
Tým Váš Hosting
Vyzkoušejte náš trial na týden zdarma

Garance 14denní záruky vrácení peněz

Vyzkoušejte server na týden zdarma

Vyzkoušet server