Jachim Coudenys z'n sessie leverde ruimschoots wat we er van verwacht hadden. Hij begon met de grondbeginselen. Een belangrijk aspect is dat PHP-FPM gebruik maakt van een masterproces dat child processen voortbrengt. Deze child processen hebben allemaal toegang tot het gedeelde geheugen van de master. 

Daarna het eerste deel: Realpath Cache. Deze cache wordt gevuld wanneer een pad wordt opgevraagd in PHP. Het explodeert een pad op het forward slash ('/') en steekt dan alle mogelijke paden in cache.

$presentation = file_get_contents( __DIR__ . '/../ffi.php' ); 
$presentation2 = file_get_contents( dirname(__DIR__) . '/ffi.php' );
$filesize = filesize( __DIR__ . '/../est.txt' ); print_r(realpath_cache_get());
[/home/jachim/demo] => Array
(
    [key] => 1.6354972010384E+19
    [is_dir] => 1
    [realpath] => /home/jachim/demo
    [expires] => 1579859105
)
[/home] => Array
(
    [key] => 4353355791257440477
    [is_dir] => 1
    [realpath] => /home
    [expires] => 1579859105
)
[/home/jachim] => Array
(
    [key] => 5522554812971572568
    [is_dir] => 1
    [realpath] => /home/jachim
    [expires] => 1579859105
)
[/home/jachim/demo /../ffi.php] => Array
(
    [key] => 1.6164035761241E+19
    [is_dir] =>
    [realpath] => /home/jachim/ffi.php
    [expires] => 1579859105
)
[/home/jachim/ffi.php] => Array
(
    [key] => 5100116734180765326
    [is_dir] =>
    [realpath] => /home/jachim/ffi.php
    [expires] => 1579859105
)
[/home/jachim/demo/realpath.php] => Array
(
    [key] => 1.8190176096283E+19
    [is_dir] =>
    [realpath] => /home/jachim/demo/realpath.php
    [expires] => 1579859105
)

Uiteraard verlopen volgende calls sneller, maar dit mechanisme maakt geen gebruik van gedeeld geheugen. Een prestatieboost kan worden bereikt door de cachegrootte en de entries TTL te tweaken.

Next up, OPCache: opcodes worden sinds PHP 5.5 gecached. Telkens wanneer een aanvraag door PHP wordt behandeld, wordt de code gecompileerd tot opcodes (kort voor operation codes). Een coole tool die Jachim liet zien, was de Vulcan Logic Dumper die deze opcodes visualiseert. Aangezien deze opcodes nooit veranderen (in productie), is het zinvol om wat cache toe te voegen. Er waren verschillende tools beschikbaar, maar het was de Zend Optimizer, die door Zend werd gedoneerd en in PHP 5.5 werd opgenomen, en het is met elke release beter geworden. Deze cache zit in het gedeelde geheugen en wordt dus door elk kind van het master FPM proces gebruikt. 

Een aantal belangrijke aspecten:

  • Shared memory: Zoals hierboven uitgelegd, wordt het gedeeld tussen de child processen, maar dit betekent ook dat het alleen nuttig is als er child processen zijn, dus misschien moet je nadenken over een aantal workarounds om de masterprocessen draaiende te houden, en zo de cache warm te houden (hoewel er andere OPCaching priming trucs zijn, zoals het opslaan van de opcodes om die in het geheugen op te slaan en te laden bij het spinnen van het masterproces, FPM-pools, etc.).
  • Verspild geheugen: OPCache doet niet aan "defragmentatie". Dit betekent dat als sommige cache-items ongeldig worden verklaard, het geheugen wordt gemarkeerd als verspild, maar het wordt niet vrijgegeven. Nieuwe items worden altijd toegevoegd. Dit kan leiden tot een suboptimaal gebruik van het beschikbare geheugen.

Er zijn verschillende opties om de configuratie te tweaken: 

  • Het is standaard uitgeschakeld voor CLI-commando's, omdat het niet zinvol is om het te cachen omdat het proces onmiddellijk wordt beëindigd. Echter, in sommige gevallen (denk dat daemons) zal het gewoon activeren je al een betere prestatie geven.  
  • Een andere voor de hand liggende winst is het verhogen van het toegestane geheugengebruik, maar het hangt af van wat de stats (opcache_get_status()) je vertellen over het huidige cachegebruik. 
  • Tweaken wanneer de cache ongeldig wordt is ook een optie. Elke revalidate_freq seconden, zal OPCache controleren op bijgewerkte scripts. Je kunt deze waarde verhogen of de instelling validate_timestamps helemaal uitschakelen, wat betekent dat de cache geldig is tot in de eeuwigheid (en handmatige ongeldigverklaring is vereist). 
  • De opcache.max_wasted_percentage is de drempel om te bepalen wanneer een herstart moet plaatsvinden om (verspild) geheugen vrij te maken.

Jachim concludeerde dat de hitrate van je OPCache altijd minimaal boven de 90% moet liggen, maar eigenlijk zou je in de meeste gevallen een hitrate van 99% moeten zien. Het verspilde geheugen zou idealiter nul moeten zijn, en je zou nooit een volledige cache moeten hebben. Een coole visualisatietool is OPcache Status.

Het laatste deel, Preloading: OPCache op steroïden. Het maakt deel uit van OPCache sinds PHP 7.4, en in principe betekent het dat sommige van uw functies en classes kunnen worden geladen wanneer PHP start, dus voordat het eventuele verzoeken accepteert. Eigenlijk worden je functies onderdeel van de PHP engine, net als bijvoorbeeld strlen(). Er is een valkuil: je klassen moeten "in volgorde" geladen worden, dat wil zeggen als je klasse een andere klasse nodig heeft, moet die al bekend zijn.

Conclusie

Ook al lijkt dit misschien devops-materie, en is het inderdaad zeer low level, maar het is zeker interessant om te weten hoe dit alles werkt, en het heeft ons team zeker weer aan het denken gezet over een aantal van onze hosting-configuraties.

Slides: https://speakerdeck.com/coudenysj/php-opcache-realpath-cache-and-preloading-phpbenelux-conference-2020

Related

This article is part of the PHPBNL20 blogs

Auteur: Wouter Aerts
Senior PHP developer
Wouter Aerts

More insights

Adressen register & GEOpunt API

Zelf al eens voor de keuze gestaan of je Google maps, openstreetmaps, of een andere GIS provider zou moeten gebruiken voor adres suggesties? Mocht je enkel Belgische adressen nodig hebben, lees dan zeker verder!

Auteur: Noah Gillard
PHP / Laravel Developer
Noah Gillard AI generated Face
Logo vlaamse overheid

Next.js: Het zoveelste framework?

Zowat om de 10 jaar komt er nieuwe technologie boven drijven, die een verandering teweeg brengt in de manier waarop we software ontwikkelen. Is Next.js deze nieuwe technologie?

Auteur: Dries Cappon
UX, Design, React.js, Next.js
Dries Cappon
Next.js

Laravel 10 release

The release of Laravel 10: The king of types. Alles wat je moet weten over de nieuwe major release!

Auteur: Noah Gillard
PHP / Laravel Developer
Noah Gillard AI generated Face
laravel 10 banner

Saloon - Package / SDK API integrations

API integraties voor een waaier aan services. Weinig tot geen herbruikbare code? Met Saloon maak je er een compacte / overzichtelijke SDK/Package van die je kan hergebruiken in al je projecten en kan maintainen op 1 plek.

Auteur: Noah Gillard
PHP / Laravel Developer
Noah Gillard AI generated Face
Saloon hero image

Codana wint Digital Champ of the year award 2022

Codana is de winnaar van de FeWeb Digital Champ award 2022

Auteur: Joris De Groot
Strategic Director and Managing Partner
Joris De Groot
FeWeb Digital Champ award Codana

De ideale eerste werkplek

Ik ben Ward Vandevoort, 22 jaar en begin november 2021 ben ik gestart bij Codana als junior backend developer. Ontdek mijn verhaal bij Codana! 

Auteur: Ward Vandevoort
Developer
Ward Vandevoort
groepsfoto