Den ofte oversete metode til hurtige PHP-forespørgsler hedder PHP Realpath Cache: Den gemmer opløste stier i arbejdshukommelsen og reducerer ressourcekrævende filsystemforespørgsler ved use of `include` og `require`. I projekter med Symfony, Laravel eller en stor WordPress-opsætning øger jeg med en velfungerende Realpath-konfiguration Ydelse målbart og holder antallet af systemkald pr. anmodning betydeligt lavere.
Centrale punkter
- Enklere Hebel: Realpath gemmer stiopløsninger og reducerer antallet af adgangsforespørgsler til filsystemet.
- Pr. medarbejder: Hver PHP-FPM-proces har sin egen Realpath-cache.
- Størrelse Vigtigt: En for lille cache forårsager thrashing og bremser anmodningerne.
- TTL bestemmer aktualiteten: Lang TTL for stabile implementeringer, kort TTL for symlinks/hemmelige oplysninger.
- Overvågning: realpath_cache_get()/size() viser udnyttelsesgraden og hullerne.
Hvad Realpath Cache præcist gør
Hver gang der bruges »include«, »require« eller »file_get_contents«, omdanner PHP relative stier til absolutte stier og gemmer resultaterne i Cache. Hvis den samme sti dukker op igen, læser jeg resultatet fra hukommelsen og sparer mig den ressourcekrævende tur til filsystem. Denne mekanisme reducerer antallet af systemkald mærkbart, især når Composer-autoloading indlæser mange klasser og konfigurationsfiler. Vigtigt: Realpath-cachen findes pr. proces, og derfor drager hver PHP-FPM-worker først fordel af den efter nogle få anmodninger, når den har opbygget sin egen cache. Dette skaber en konstant hastighedsforøgelse, der især betaler sig ved høj belastning.
Hvorfor cachen er vigtig i store framework
Store rammeværker og mange plugins genererer utallige pr. anmodning Fildadgang, som uden caching ville være nødt til at opløse stierne hver gang. Hvis Realpath-cachen er for lille, fortrænger den ældre poster, nye kommer til, og jeg observerer ren Smadrer. Dette resulterer i gentagne stat- og lookup-operationer, som tager tid og belaster I/O. I praksis kan antallet af systemkald pr. anmodning dermed reduceres med ca. 5–15 %, hvilket i praksis udgør en betydelig besparelse ved en høj anmodningsfrekvens. Jo mere modulær applikationen er, desto større er gevinsten ved en korrekt dimensioneret Realpath-cache.
Sådan finder jeg den rigtige cache-størrelse
Først tæller jeg de unikke stier i en typisk anmodning, estimerer den gennemsnitlige stilængde og lægger ca. 128 byte til pr. post Overhead. Ud fra antallet, stiens længde og overhead beregner jeg en realpath_cache_size, der er tilstrækkelig Buffer tilbyder. Mange større projekter ender på mellem 4 og 16 MiB, og meget omfattende monorepos kan også overstige dette. Det er vigtigt, at cachen ikke når sin grænse, ellers går fordelen tabt på grund af konstant rydning. Jeg øger kapaciteten trinvis, overvåger udnyttelsen og justerer efter behov.
Anbefalede indstillinger og eksempelværdier
Standardværdierne stammer fra en tid med små kodebaser og passer ofte ikke længere til nutidens Opsætninger. I mange produktive applikationer indstiller jeg realpath_cache_size til mellem 4096K og 16384K og forlænger realpath_cache_ttl til 360–600 Sekunder eller mere. Det afgørende er projektets størrelse, implementeringsfrekvensen og filsystemets karakter. Den følgende tabel viser nyttige vejledende værdier og hjælper med at komme i gang med optimeringen. Derefter justerer jeg tallene på baggrund af overvågning og belastningstests.
| Indstilling | Hyppige misligholdelser | Gode udgangsværdier | Forventet effekt |
|---|---|---|---|
| realpath_cache_size | 4096K (4 MiB) | 4096K–16384K | Reduceret Smadrer når der er mange filer |
| realpath_cache_ttl | 120–600 s | 360–900 s | Længere Cache-stop, færre gentagne opløsninger |
Eksempler i php.ini: realpath_cache_size = 4096K og til store rammeværker realpath_cache_size = 16384K. I hverdagen bruger jeg ofte realpath_cache_ttl = 360 eller højere ved sjældne udgivelser. På den måde forbliver stierne i hukommelsen gennem mange anmodninger, uden at de hele tiden skal valideres på ny.
Vælg TTL med omhu – afhængigt af implementeringen
Den korrekte TTL afhænger i høj grad af implementeringsprocessen og brugen af Symlinks . Når jeg skifter mellem udgivelser ved hjælp af symlink-rotation, må cachen ikke levere forældede stier, derfor indstiller jeg TTL til en kort tid eller udløser en FPM-genstart efter Udrulning. I Kubernetes-miljøer, hvor Secrets eller ConfigMaps bruges som volumes, reducerer jeg TTL markant eller deaktiverer Realpath-cachen midlertidigt. Mere statiske webhosting-situationer drager derimod fordel af længere TTL’er, da stierne sjældent ændrer sig. På den måde finder jeg den rette balance mellem aktualitet og hastighed, alt efter miljøet.
Overvågning og verifikation
Jeg tjekker regelmæssigt med realpath_cache_get(), hvilke stier i Cache ligger, og med realpath_cache_size(), hvor meget af den er optaget. Hvis brugen nærmer sig den konfigurerede størrelse, øger jeg den Kapacitet Trin for trin. Hvis cachen fyldes op ekstremt hurtigt, tolker jeg det som et tegn på, at der er brug for mere hukommelse, eller at TTL-værdien er for kort. Efter større plugin-installationer eller framework-opdateringer tjekker jeg det igen. Kun den, der kender tallene, kan træffe fornuftige beslutninger om optimering.
Målbar effekt: Sådan måler jeg systemkald og latenstider
For at sikre, at optimeringen er robust, foretager jeg målinger før og efter ændringerne. På Linux registrerer jeg filsystemkald pr. anmodning med strace eller perf, enten på en enkelt FPM-worker eller via CLI.
- Enkelt anmodning (CLI):
strace -c -o /tmp/strace.txt php public/index.phpgiver et overblik over, hvor mangestat(),openat()oglstat()opstår. - Vedhæft FPM-arbejder:
strace -fp -e trace=file -o /tmp/strace-fpm.logviser kun filrelaterede opkald. Tidligere medpsBestemme arbejdsprocessens PID. - Belastningstest: Med værktøjer som
fraellerhejJeg simulerer belastning og sammenligner P95/P99-latenser ved forskellige cache-størrelser.
Samtidig får jeg PHP til at vise cache-belægningen, for eksempel i et debug-endpoint eller via CLI:
<?php
$entries = realpath_cache_get();
$size = realpath_cache_size();
printf("Entries: %d, Used: %d bytes (%.2f MiB)\n", count($entries), $size, $size/1048576);
Sådan kan jeg se, om stigningen i realpath_cache_size faktisk reducerer antallet af fejl og filsystemkald i stedet for blot at optage RAM. Ideelt set stiger hitraten, mens P95-latenserne falder mærkbart.
Sådan varmer jeg Realpath-cachen målrettet op
Da cachen oprettes for hver enkelt worker, er det en god idé at Opvarmning efter en implementering eller genstart. Målet er, at de mest hyppige includes kommer tidligt i cachen, inden den egentlige brugertrafik begynder.
- Anmodninger om genudsendelser: Efter udrulningen kører jeg automatisk en håndfuld typiske URL’er (frontend, admin, API).
- CLI-priming: Et kort bootstrapping-script indlæser centrale stier (autoloader, kerne, konfiguration, ruter).
<?php
// warmup.php
require __DIR__.'/vendor/autoload.php'; // Composer
require __DIR__.'/config/bootstrap.php'; // Afhænger af projektet
require __DIR__.'/public/index.php'; // Front-Controller (kan udløse en kort kørsel)
echo sprintf("Primed %d entries, used %d bytes\n",
count(realpath_cache_get()), realpath_cache_size());
Denne opvarmning dækker ganske vist ikke alle reelle anmodninger, men lagrer de mest anvendte stier og forkorter den indledende koldstartfase mærkbart for hver worker.
Samspil med OPcache og filsystemcachen
OPcache gør udførelsen af PHP-filer hurtigere, mens Realpath forkorter stien til filen, så jeg kombinerer de to Teknikker. Til OPcache-indstillingerne bruger jeg gennemprøvede værdier og henviser til velunderbyggede OPcache-optimering, så bytecode og stier fungerer optimalt sammen. Derudover drager Realpath fordel af en »varm« OS-cache, der hurtigt leverer mappeopslag og metadata. På den måde undgår jeg dobbelt ventetid ved indlæsning og parsning. Hvis man koordinerer begge niveauer, opnår man mærkbare forbedringer i responstiden.
Få mest muligt ud af Composer-autoloading
Composer-Autoloader er en af de vigtigste drivkræfter bag stiopløsninger. Jo mere deterministisk den fungerer, desto lettere har Realpath-cachen det.
- Optimere Classmap:
composer dump-autoload -oreducerer katalogscanninger og gentagne opslag. - Overhold strengt autoloadMed
classmap-autoritativ(Projektsammenhæng) undgår jeg unødvendige fallbacks, som ellers ville udløse yderligere stiopløsninger. - Organisere strukturen: Flade, ensartede mappehierarkier og få undtagelser (f.eks. inkluderinger på tværs af moduler eller klienter) stabiliserer belastningen på cachen.
Resultatet: færre forskellige stier pr. anmodning, mere genbrug i Realpath-cachen og dermed lavere IO-omkostninger.
FPM og memory-budget: hvad der er realistisk pr. worker
Da Realpath-cachen findes pr. proces, ganges den konfigurerede størrelse med antallet af FPM-workere. Derfor planlægger jeg et budget:
- Eksempel: 12 arbejdsprocesser × 8 MiB = 96 MiB Realpath-hoved; hertil kommer OPcache, PHP-heap og overhead fra udvidelser.
- Afbalancering: Hvis OPcache har rigelig plads, kan Realpath få nogle MiB mere – eller omvendt.
- Specifikt for poolen: Forskellige FPM-puljer (Front, Admin, API) må have forskellige Realpath-størrelser, afhængigt af det pågældende kodens omfang.
Jo mere koden vokser med hver udgivelse, jo mere vokser realpath_cache_size-behovet typisk med. Derfor kontrollerer jeg regelmæssigt spidsbelastningen under belastning, ikke kun i tomgang.
Særlige tilfælde: Symlinks, containere og NFS
Når der gennemføres symlink-udrulninger, skriver jeg en kort TTL eller genstart FPM efter implementeringen, så alle workere indlæser de nye stier. I containere med variable volumener sørger jeg for, at cachen ikke indeholder forældede Mål ved at justere TTL. Ved brug af NFS anbefales det desuden at anvende en velfungerende OPcache-strategi og så få skift mellem mapper som muligt. Hvis stierne ændrer sig under kørsel, tømmer jeg i tvivlstilfælde målrettet med clearstatcache(true) også Realpath-delen. Tydelige implementeringsregler forhindrer inkonsekvente tilstande på tværs af workerne.
Typiske forhindringer og begrænsninger
Da cachen eksisterer pr. proces, skal hver enkelt Arbejder Først og fremmest skal der indsamles stier, før effekten træder i kraft. I opsætninger med strenge open_basedir-begrænsninger fungerer Realpath-cachen kun i begrænset omfang, derfor tager jeg højde for dette Grænser ved planlægningen. For små cacher fører til thrashing, for store cacher spilder RAM – jeg finder det optimale punkt ved hjælp af målinger. Desuden er jeg opmærksom på, at Realpath ikke er en metadata- eller indholdscache, men udelukkende gemmer stiopløsninger. Hvis man har forkerte forventninger, overser man årsagerne andre steder.
Driftssikkerhed: typiske fejl og hurtige kontroller
Nogle symptomer tyder tydeligt på Realpath-problemer – og kan hurtigt bekræftes:
- Ujævne ventetider efter implementering: Enten for lang TTL ved symlink-rotation eller manglende opvarmning. Løsning: kort TTL, genstart af FPM, efterfulgt af priming.
- Mange gentagne
stat()-visningerMedstracesynlig; ofte er cache-størrelsen for lille, eller visse dynamiske stier fortrænger hot-entries. - Stor variation mellem arbejdere: Forskellige cacher pr. proces. Løsning: ensartet opvarmning og jævn fordeling af anmodninger.
Ofte er det nok med en hurtig sundhedstjek via PHP:
<?php
$entries = realpath_cache_get();
$byDir = 0; $byFile = 0;
foreach ($entries as $e) { $e['is_dir'] ? $byDir++ : $byFile++; }
printf("Mapper: %d, Filer: %d, Brugt: %.2f MiB\n", $byDir, $byFile, realpath_cache_size()/1048576);
På den måde kan jeg se, om det især er mapper (mange moduler, leverandørstrukturer) eller filer (mange konfigurationsfiler/klasser), der dominerer cachen – og tilpasse strukturen eller størrelsen derefter.
Stat-cache vs. Realpath-cache: en bevidst skelnen
Ud over Realpath-cachen har PHP også en Stat-Cache for resultater fra stat() og lignende opkald. Begge cacher kan hentes med clearstatcache() påvirke:
clearstatcache()tømmer Stat-cachen (valgfrit for en bestemt fil).clearstatcache(true)tømmer desuden Realpath-cachen.
I sjældne tilfælde – f.eks. ved langvarigt kørende CLI-workere med dynamiske mounts eller ved hot-swaps – bruger jeg en målrettet clearstatcache(true)-Hook efter kendte ændringer. Ellers lader jeg TTL fungere og undgår unødvendige ugyldiggørelser.
Praktisk tjekliste for hostingmiljøer
Først fastslår jeg projektets omfang, altså hvor mange filer en typisk anmodning indlæser, og derefter tjekker jeg belastningen på Cacher. Derefter vælger jeg en realpath_cache_size, der rummer alle hyppigt anvendte stier plus en reserve, og indstiller en TTL, der passer til deploy-frekvensen. Herefter overvåger jeg effekterne ved hjælp af overvågning og logfiler og justerer værdierne forsigtigt i stedet for at øge dem drastisk. Derudover er det værd at kigge på OS-cachen, f.eks. på Linux-indstillingen VFS-cache-tryk, fordi Realpath drager fordel af hurtige mappeopslag. På den måde kan jeg indføre forbedringer uden at overse eventuelle bivirkninger.
Omfang og konfigurationsmetoder: hvor jeg indstiller hvilke værdier
Afhængigt af omgivelserne vedligeholder jeg parametrene forskellige steder:
- Globalt:
php.initil systemomfattende standardindstillinger. - Pro-Pool: I FPM-puljer pr.
php_admin_value[realpath_cache_size]ogphp_admin_value[realpath_cache_ttl]dimensionere dem målrettet forskelligt til frontend og API. - Pro-katalog: I
.user.ini(hvis det er tilladt), hvilket er hensigtsmæssigt i shared hosting-miljøer.
Vigtigt: Ændringer i php.ini og FPM-pool-konfigurationer kræver en genstart eller en genindlæsning, for at workerne kan starte med de nye værdier.
CLI, kø-arbejdere og cron-jobs: de samme regler, forskellige kørselstider
CLI-scripts og kø-arbejdere drager også fordel af Realpath-cachen – dog er Levetid ofte anderledes:
- Kortvarige CLI-opgaver: Cachen oprettes på ny ved hvert opkald. Her hjælper opvarmning og en lang TTL ikke meget; det er snarere vigtigt, at cachen er stor nok, så gentagne includes i selve jobbet caches.
- Daemons/Worker: Langvarige processer (Supervisor, Systemd) opbygger en stabil cache. Efter en Genindlæsning af kode (Deploy) bør processen genstartes, ellers kan der blive hængende forældede stier i cachen.
Vurdering af projektstørrelser og lagringseffekt
Et program med 4000 unikke stier og en stilængde på 80 byte plus 128 byte overhead pr. post kræver groft sagt 832 KB Hukommelse i Realpath-cachen; jeg regner med 4 MiB eller mere som reserve. Hvis kodebasen vokser markant på grund af plugins eller moduler, skalerer jeg lineært i takt hermed og tjekker igen Hits versus fejl. På shared-hosts holder jeg desuden øje med inode-grænserne, fordi for mange små filer belaster hele systemet; denne oversigt hjælper mig med det Inode-grænser. Det er bedre at regne med en sikkerhedsmargen end at køre konstant på grænsen. På den måde sparer jeg på systemkald uden unødvendigt RAM-forbrug.
Kort og præcist: Min plan for tuning
Først måler jeg antallet af filer pr. anmodning, derefter indstiller jeg en passende Cache-størrelse og en, der passer til den konkrete implementeringspraksis TTL. Derefter kontrollerer jeg belastningen med realpath_cache_get()/size(), justerer trin for trin og kombinerer det hele med finjustering af OPcache og OS-cache. Ved udrulning af symlinks holder jeg TTL kort eller genstarter FPM, mens jeg i statiske miljøer bruger lange levetider. Målet er fortsat en høj cache-hitrate uden spild af RAM. På den måde udnytter jeg Realpath-cachen som en undervurderet turbo til konsistent PHP-ydeevne.


