Wat is PHP OPcache en waarom is het belangrijk?
PHP is de programmeertaal achter een groot deel van het web. Van WordPress en Laravel tot complexe webshops en SaaS-applicaties: bij ieder verzoek moet PHP code uitvoeren om een pagina of API-response te genereren.
Voordat PHP die code kan uitvoeren, moet deze eerst worden gecompileerd naar opcode: instructies die de PHP-engine begrijpt.
Dat compileren kost tijd en rekenkracht. Gelukkig hoeft dat dankzij PHP OPcache niet bij ieder verzoek opnieuw te gebeuren. OPcache bewaart de gecompileerde code in het geheugen, zodat PHP die bij volgende verzoeken direct kan hergebruiken.
OPcache zit sinds PHP 5.5 in PHP zelf. In de releasenotes van die versie, van 20 juni 2013, staat het in één regel: “Added the Zend OPcache extension for opcode caching.” Daarvoor installeerde je zelf een opcode-cache, meestal APC.
Dat levert een aanzienlijke prestatieverbetering op, vaak minstens 50%. Maar er zit een addertje onder het gras: wat gebeurt er als tientallen of honderden websites dezelfde server, en dus dezelfde OPcache delen?
Wat is PHP-FPM?
PHP-code wordt vaak uitgevoerd door PHP-FPM: de FastCGI Process Manager. Je webserver neemt het verzoek van de bezoeker aan en geeft het door aan PHP-FPM, dat de PHP-processen draait en beheert.
Het probleem: één OPcache voor alle websites
Op veel traditionele hostingomgevingen, bijvoorbeeld servers met DirectAdmin, Plesk of een typische VPS, draait één PHP-FPM-masterproces per PHP-versie.
Onder dat masterproces kunnen meerdere PHP-FPM-pools draaien, bijvoorbeeld één per website of UNIX-gebruiker.
Dat klinkt als een nette scheiding. Iedere website heeft immers zijn eigen processen. Maar al deze pools - dus iedere website - gebruikt dezelfde OPcache: die wordt opgeslagen in het ene masterproces.
Hoe meer websites, hoe groter het probleem
Stel dat een hostingserver honderd websites draait. De ene is een eenvoudige WordPress-site, de andere een omvangrijke Laravel-applicatie en weer een andere een drukbezochte webshop.
Al die websites gebruiken PHP-code die idealiter in OPcache wordt opgeslagen.
Maar de OPcache - die een beperkte grootte heeft - wordt dus opgeslagen in het ene masterproces, en daarmee gedeeld door alle pools (websites).
Hoe meer sites je op een server host, hoe groter de kans dat niet alle gecompileerde scripts meer kunnen worden gecachet: alle websites zijn dan continu aan het vechten voor ruimte in de (beperkte) OPcache. PHP moet daardoor vaker code opnieuw compileren, waardoor projecten trager worden.
Een drukke of omvangrijke applicatie kan zo indirect invloed hebben op de prestaties van andere websites op dezelfde server.
Je kunt dit deels ondervangen door OPcache ruim te configureren, en het gebruik voortdurend te monitoren. Maar dat betekent dat iemand moet blijven controleren of de cache groot genoeg is voor alle websites samen, én de instellingen moet aanpassen wanneer dat niet meer zo is. En wat als een site of applicatie tijdelijk wat meer cachet? Dan hebben alle andere projecten daar gelijk last van.
Voor een webbureau, ontwikkelaar of SaaS-bedrijf zou dat niet nodig moeten zijn. Je wilt je bezighouden met je applicaties en klanten, niet met het optimaliseren van een cache!
De oplossing: een eigen PHP-FPM-masterproces per project
Bij Cyberfusion pakken we OPcaching anders aan, zodat jullie projecten niet alleen snel zijn, maar ook blijven.
Sinds 2020 krijgt ieder project een eigen masterproces, in plaats van alleen een eigen PHP-FPM-pool onder een gedeelde master.
Dat levert twee belangrijke voordelen op.
1. Een eigen OPcache voor ieder project
Omdat ieder project zijn eigen PHP-FPM-masterproces heeft, beschikt het ook over een eigen OPcache.
Stel dat PHP is geconfigureerd met opcache.memory_consumption=128. Op een traditionele hostingomgeving moeten alle projecten onder hetzelfde PHP-FPM-masterproces die 128 MB samen delen. Bij Cyberfusion krijgt ieder project zijn eigen 128 MB OPcache.
Daardoor hoeft een site of applicatie zijn cacheruimte niet te delen met tientallen andere projecten op dezelfde server. En andersom kan een drukke website niet zomaar de OPcache van andere projecten onder druk zetten.
Resultaat: voorspelbare prestaties, ook wanneer er steeds meer projecten op dezelfde server worden geplaatst. Je projecten zijn niet alleen snel, maar blijven dat ook.
2. Betere beveiliging: geen inzage in de OPcache van andere projecten
Een gedeelde OPcache heeft niet alleen gevolgen voor de prestaties, maar ook voor de beveiliging.
PHP biedt bijvoorbeeld de functie opcache_get_status(). Daarmee kun je zien welke PHP-bestanden in OPcache zijn opgeslagen, hoeveel geheugen ze gebruiken en hoe vaak ze worden aangeroepen.
Handig om je eigen applicatie te analyseren. Maar op een traditionele PHP-FPM-configuratie kun je hiermee standaard ook informatie over andere websites op dezelfde server opvragen. Inclusief de volledige bestandspaden van PHP-scripts van andere klanten.
Vanuit beveiligingsperspectief is dat natuurlijk allesbehalve wenselijk.
Sommige hostingproviders lossen dit op door dergelijke functies uit te schakelen via disable_functions, of de toegang ertoe te beperken. Maar daarmee bestrijd je vooral het symptoom: de onderliggende OPcache wordt nog steeds gedeeld. Bovendien verlies je als ontwikkelaar nuttige mogelijkheden om je eigen applicatie te analyseren.
Doordat ieder project bij Cyberfusion zijn eigen PHP-FPM-masterproces en OPcache heeft, kun je gewoon opcache_get_status() gebruiken, zonder daarmee inzicht te krijgen in de OPcache van andere projecten.
Benieuwd of jouw huidige hostingomgeving OPcache-informatie over andere sites 'lekt'? Probeer opcache_get_status() eens op je VPS of hostingserver. Zie je alleen je eigen applicatie, of ook bestanden van andere websites?
Een bewuste keuze sinds 2020
Toen we deze architectuur in 2020 introduceerden, was het draaien van meerdere PHP-FPM-masterprocessen per server niet erg gebruikelijk.
Een leuke bevestiging kregen we van Volker Dusch, die betrokken is bij het officiële PHP-project:
Great to hear. That sounds very reasonable from a performance perspective to me.
Is er ook een nadeel? Soort van: extra geheugenverbruik
Meerdere PHP-FPM-masterprocessen draaien kost (iets) meer resources.
Uit onze eigen metingen blijkt dat ieder PHP-FPM-masterproces ongeveer 40 tot 50 MB RAM kost.
Zoals gezegd: op een standaard-hostingomgeving heb je één PHP-FPM-masterproces per versie. Dan hebben we het dus over tientallen tot een paarhonderd MiB RAM, 'at most'.
Met een PHP-FPM-masterproces per project, hebben we het bij honderd projecten over 5 GB aan extra geheugenverbruik, nog los van het geheugen dat voor de afzonderlijke OPcache-instanties wordt gereserveerd.
Voor omgevingen die performance en veilligheid vereisen, wegen de voordelen ruimschoots op tegen de hogere geheugenbelasting.
Werkgeheugen is uiteindelijk een middel om een doel te bereiken: een snel, veilig en betrouwbaar hostingplatform. Het heeft weinig zin om enkele gigabytes te besparen als daardoor de prestaties van tientallen projecten onvoorspelbaarder worden.
Waarom dit voor webbureaus en SaaS-bedrijven belangrijk is
Als webbureau wil je websites bouwen, onderhouden en verbeteren. Als SaaS-bedrijf of platform wil je je product ontwikkelen.
In beide gevallen wil je niet voortdurend moeten onderzoeken waarom een applicatie ineens langzamer reageert, terwijl de CPU- en geheugengrafieken van de server er prima uitzien.
Toch kunnen juist dit soort problemen ontstaan op traditionele hostingplatformen (zoals DirectAdmin, VPS en Forge) waar projecten dezelfde resources delen.
Het vervelende is bovendien dat je een gedeelde OPcache meestal niet direct als oorzaak herkent. Je ziet een tragere website, maar de server lijkt niet overbelast.
Cyberfusion Core, het échte managed-hostingplatform voor webprofessionals, is zo ontworpen dat veelvoorkomende knelpunten al op architectuurniveau worden voorkomen. Een afzonderlijk PHP-FPM-masterproces en een eigen OPcache per project zijn daar voorbeelden van.
Goede hosting begint onder de motorkap
Snelle PHP-hosting draait om meer dan krachtige hardware, snelle SSD’s of veel CPU-cores. De manier waarop websites en applicaties op een server worden georganiseerd, is minstens zo belangrijk.
Dat is échte managed-hosting: technische keuzes maken die problemen voorkomen, zodat onze klanten zich kunnen richten op het bouwen van sites en applicaties.