OPcache: the good, the bad and the ugly

Al onze PHP-servers zijn voorzien van OPcache, een manier om PHP-bestanden te "compileren", zodat ze sneller uitgevoerd worden. Dit is absoluut noodzakelijk, maar zorgt soms voor misverstanden. Hoe zit de vork aan de steel?

Al onze PHP-servers zijn voorzien van OPcache, een manier om PHP-bestanden te "compileren", zodat ze sneller uitgevoerd worden. Dit is absoluut noodzakelijk, maar zorgt soms voor misverstanden. Hoe zit de vork aan de steel?

The good

Wat is OPcache nu precies? Telkens dat je een PHP-script uitvoert, moet dit script vertaald worden naar machinecode, wat tijd kost. OPcache houdt deze machinecode in het geheugen, waardoor hetzelfde script de volgende keer niet opnieuw vertaald moet worden. Het kan dus onmiddellijk uitgevoerd worden, wat je applicatie bijgevolg versnelt en serverkosten bespaart.

Waarover praten we eigenlijk?

Wat is met andere woorden  de performantiewinst die we hieruit halen? Dat hangt natuurlijk af van je applicatie, maar laten we even als voorbeeld een lege Symfony installatie installeren op een klein servertje bij Amazon Web Services (AWS).

Ja, met benchmarks kan je alles bewijzen, dat weet ik. Maar we gaan het hier heel eenvoudig houden.
Dit is het resultaat van 100 requests naar die lege Symfony-installatie:

Peter:~ peter$ ab -n 100 http://symfony.lunatis.eu/
Time per request:       81.423 [ms] (mean)
Time per request:       81.423 [ms] (mean, across all concurrent requests)

Dit is natuurlijk de geoptimaliseerde Symfony die je ziet. Als we naar de app_dev.php gaan, zien we dat dit trager is, wat we natuurlijk al konden verwachten:

Peter:~ peter$ ab -n 100 http://symfony.lunatis.eu/app_dev.php
Time per request:       146.606 [ms] (mean)
Time per request:       146.606 [ms] (mean, across all concurrent requests)

Bij de app_dev.php wordt er in Symfony minder uit cached templates geserveerd, dus zijn er meer PHP-bestanden te raadplegen en in het geheugen te laden.

Als we dan OPcache uitschakelen, zien we het volgende:
Peter:~ peter$ ab -n 100 http://symfony.lunatis.eu/
Time per request:       109.885 [ms] (mean)
Time per request:       109.885 [ms] (mean, across all concurrent requests)

Peter:~ peter$ ab -n 100 http://symfony.lunatis.eu/app_dev.php
Time per request:       217.703 [ms] (mean)
Time per request:       217.703 [ms] (mean, across all concurrent requests)

Dus:

  • De / gaat van 109.885ms naar 81.423ms: een verbetering van 26%
  • De app_dev.php gaat van 217.703ms naar 146.606: een verbetering 32%

De conclusie is duidelijk: OPcache zorgt voor een duidelijke verbetering in snelheid. Hoe complexer en hoe meer PHP-bestanden er verwerkt moeten worden hoe beter. Bij een Wordpress met veel plugins ga je nog veel meer verschillen zien.

Nog verder?

Voor de liefhebbers kunnen we onze OPcache nog wat agressiever instellen. Dit zetten we dan in onze OPcache-configuratie:

opcache.max_accelerated_files=20000
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.validate_timestamps=0
opcache.fast_shutdown=1
opcache.enable-file-override=1

Met als resultaat:

Peter:~ peter$ ab -n 100 http://symfony.lunatis.eu/
Time per request:       72.566 [ms] (mean)
Time per request:       72.566 [ms] (mean, across all concurrent requests)

Met deze meer agressieve instellingen kan je nog een beetje tijd winnen. Het komt wel met een nadeel, lees zeker verder!

By the way: jij hoeft niet in configuratiebestanden te rommelen. In ons controlepaneel kan je eenvoudig kiezen tussen de OPcache-configuraties met 1 druk op de knop.

The bad

Je mag OPcache dus gerust noodzakelijk noemen. Maar hou één ding altijd in het achterhoofd.

Omdat OPcache je PHP-bestanden in cache houdt, zijn gewijzigde bestanden niet altijd onmiddellijk zichtbaar. Dit fenomeen zorgt soms voor verwarring en errors in PHP.
Daarom is het belangrijk om tijdens een deploy van een website, zeker als de OPcache-configuratie op agressief staat ingesteld, ook steeds de OPcache te clearen! Hier zijn verschillende methodes voor. Een van de methodes, als je een eigen server hebt, is PHP-FPM te herstarten:

service php7.0-fpm restart

The ugly

Niets lelijk aan OPcache. Ik vond het alleen mooi klinken en het deed me hieraan denken:

 

Vragen of opmerkingen?

Laat het ons zeker weten via onze chatbox!
We helpen je graag verder.

Deel deze blog via