...

Cache Realpath PHP : un accélérateur sous-estimé pour les performances PHP

Le levier, souvent négligé, qui permet d'accélérer les requêtes PHP s'appelle PHP Realpath Cache : il stocke les chemins résolus en mémoire vive et réduit les requêtes coûteuses au système de fichiers lors des instructions `include`/`require`. Dans les projets utilisant Symfony, Laravel ou une installation WordPress de grande envergure, j'améliore les performances grâce à une configuration soignée de Realpath. Performance mesurable et permet de maintenir un nombre nettement plus faible d'appels système par requête.

Points centraux

  • Plus simple Levier : Realpath enregistre les résolutions de chemins d'accès et réduit les accès au système de fichiers.
  • Par travailleur: Chaque processus PHP-FPM gère son propre cache Realpath.
  • Taille À noter : un cache trop petit provoque un « thrashing » et ralentit les requêtes.
  • TTL détermine la fréquence de mise à jour : TTL long pour les déploiements stables, court pour les liens symboliques et les secrets.
  • Suivi: les fonctions realpath_cache_get() et size() indiquent le taux d'utilisation et les espaces vides.

Ce que fait exactement le cache Realpath

À chaque appel de `include`, `require` ou `file_get_contents`, PHP convertit les chemins relatifs en chemins absolus et enregistre ces résultats dans le fichier Cache. Si le même chemin est à nouveau parcouru, je lis le résultat dans la mémoire et j'évite ainsi un accès coûteux au système de fichiers. Ce mécanisme réduit sensiblement le nombre d'appels système, notamment lorsque l'autochargement de Composer charge de nombreuses classes et fichiers de configuration. Important : le cache Realpath existe par processus ; par conséquent, chaque worker PHP-FPM n'en tire profit qu'après quelques requêtes, une fois qu'il a constitué son propre cache. Il en résulte un effet d'accélération constant, particulièrement bénéfique en cas de charge élevée.

Pourquoi le cache joue un rôle important dans les grands frameworks

Les grands frameworks et les nombreux plugins génèrent d'innombrables Accès aux fichiers, qui, sans mise en cache, devraient résoudre les chemins à chaque fois. Si le cache Realpath est trop petit, il remplace les anciennes entrées par les nouvelles, et j'observe un pur Thrashing. Il en résulte des opérations répétées de calcul de statistiques et de recherche, qui prennent du temps et sollicitent les E/S. Concrètement, cela permet de réduire le nombre d'appels système par requête d'environ 5 à 15 %, ce qui, avec un taux de requêtes élevé, finit par représenter un gain considérable. Plus l’application est modulaire, plus l’effet de levier obtenu grâce à un cache Realpath correctement dimensionné est important.

Voici comment déterminer la taille de cache appropriée

Je commence par compter le nombre de chemins uniques d'une requête type, j'estime la longueur moyenne d'un chemin et j'ajoute environ 128 octets par entrée Overhead. À partir du nombre, de la longueur du chemin et de la surcharge, je déduis une valeur realpath_cache_size suffisante Tampon offre. De nombreux projets de grande envergure occupent entre 4 et 16 Mio, et les monorepos très volumineux peuvent même dépasser cette limite. Il est important que la mémoire cache ne soit pas saturée, sinon je perds tout l'intérêt de cette fonctionnalité à force de devoir la vider constamment. J'augmente la taille par paliers, j'observe l'utilisation de la mémoire et j'ajuste en conséquence.

Paramètres recommandés et exemples de valeurs

Les valeurs par défaut datent d'une époque où les bases de code étaient plus modestes et ne correspondent souvent plus aux réalités actuelles Configurations. Pour de nombreuses applications de production, je règle realpath_cache_size entre 4096K et 16384K et je prolonge realpath_cache_ttl à une durée comprise entre 360 et 600 secondes ou plus. La taille du projet, la fréquence de déploiement et les caractéristiques du système de fichiers sont déterminantes. Le tableau suivant présente des valeurs de référence utiles pour s'orienter et facilite le démarrage du processus d'optimisation. Je procède ensuite à un ajustement de ces chiffres à l'aide de la surveillance et de tests de charge.

Réglage Défaut de paiement fréquent De bons résultats de départ Effet escompté
realpath_cache_size 4096 K (4 Mio) 4 096 K – 16 384 K Réduit Thrashing lorsqu'il y a beaucoup de fichiers
realpath_cache_ttl 120 à 600 s 360 à 900 s Plus longues Arrêts de cache, moins de nouvelles dissolutions

Exemples dans le fichier php.ini : realpath_cache_size = 4096 Ko et pour les grands frameworks realpath_cache_size = 16384K. Pour la durée de vie, j'utilise souvent realpath_cache_ttl = 360 ou plus pour les versions rares. Ainsi, les chemins restent en mémoire pendant de nombreuses requêtes, sans être constamment revalidés.

Choisir judicieusement le TTL – en fonction du déploiement

La durée de vie (TTL) appropriée dépend fortement du processus de déploiement et de l'utilisation de Liens symboliques . Lorsque je bascule entre les versions via la rotation des liens symboliques, le cache ne doit pas fournir de chemins obsolètes ; c'est pourquoi je définis un TTL court ou je déclenche un redémarrage de FPM après le Déploiement. Dans les environnements Kubernetes utilisant des Secrets ou des ConfigMaps comme volumes, je réduis considérablement la durée de vie (TTL) ou je désactive temporairement le cache Realpath. En revanche, les environnements d'hébergement web plus statiques tirent profit de durées de vie plus longues, car les chemins d'accès changent rarement. C’est ainsi que je trouve le juste équilibre entre actualité et vitesse en fonction de l’environnement.

Surveiller et vérifier

Je vérifie régulièrement avec realpath_cache_get(), quels chemins dans le Cache se trouvent, et avec realpath_cache_size(), quelle part de l'espace de stockage est occupée. Si l'utilisation avoisine la taille configurée, j'augmente la Capacité Petit à petit. Si le cache se remplit extrêmement vite, j'y vois un signe qu'il faut augmenter la mémoire ou que la durée de vie (TTL) est trop courte. Je vérifie à nouveau après des installations importantes de plugins ou des mises à jour du framework. Seul celui qui connaît les chiffres peut prendre des décisions judicieuses en matière d'optimisation.

Impact mesurable : comment mesurer les appels système et les latences

Pour m'assurer de la robustesse de l'optimisation, je procède à des mesures avant et après les modifications. Sous Linux, je comptabilise les appels au système de fichiers par requête à l'aide de strace ou parfait, soit sur un seul worker FPM, soit via l'interface en ligne de commande (CLI).

  • Requête unique (CLI): strace -c -o /tmp/strace.txt php public/index.php donne un aperçu du nombre de stat(), openat() et lstat() être générés.
  • Ajouter un travailleur FPM: strace -fp -e trace=fichier -o /tmp/strace-fpm.log n'affiche que les appels liés à des fichiers. Auparavant, avec ps Déterminer le PID du worker.
  • Test de charge: Grâce à des outils tels que à partir de ou salut Je simule une charge et je compare les latences P95/P99 pour différentes tailles de cache.

En parallèle, je fais afficher l'occupation du cache depuis PHP, par exemple dans un point de terminaison de débogage ou via la CLI :

<?php
$entries = realpath_cache_get();
$size    = realpath_cache_size();
printf("Entrées : %d, Utilisées : %d octets (%.2f Mio) \n", count($entries), $size, $size/1048576);

Voici comment je détermine si l'augmentation de la realpath_cache_size réduit effectivement les échecs et les appels au système de fichiers, au lieu de simplement monopoliser la mémoire vive. Idéalement, le taux de réussite augmente tandis que les latences P95 diminuent sensiblement.

Voici comment je préchauffe le cache Realpath de manière ciblée

Comme le cache est créé pour chaque worker, il est intéressant de Echauffement après le déploiement ou le redémarrage. L'objectif est que les fichiers inclus les plus fréquents soient mis en cache rapidement, avant l'arrivée du trafic réel des utilisateurs.

  • Rediffusions de requêtes: Après le déploiement, j'effectue automatiquement des tests sur une poignée d'URL types (interface utilisateur, espace d'administration, API).
  • Initialisation de la CLI: Un petit script de démarrage charge les chemins d'accès principaux (autochargeur, noyau, configuration, routes).
<?php
// warmup.php
require __DIR__.'/vendor/autoload.php';  // Composer
require __DIR__.'/config/bootstrap.php'; // En fonction du projet
require __DIR__.'/public/index.php' ;     // Contrôleur frontal (peut déclencher une exécution courte)
echo sprintf("Entrées %d préparées, %d octets utilisés\n",
    count(realpath_cache_get()), realpath_cache_size());

Bien que cet « échauffement » ne couvre pas toutes les requêtes réelles, il enregistre les chemins les plus fréquemment empruntés et réduit sensiblement la phase initiale de démarrage à froid pour chaque worker.

Interaction avec OPcache et le cache du système de fichiers

OPcache accélère l'exécution des fichiers PHP, tandis que Realpath raccourcit le chemin d'accès au fichier ; c'est pourquoi je combine les deux Techniques. Pour les paramètres d'OPcache, j'utilise des valeurs qui ont fait leurs preuves et je renvoie à des sources fiables Optimisation d'OPcache, afin que le bytecode et les chemins d'accès fonctionnent en parfaite harmonie. De plus, Realpath bénéficie d'un cache système « chaud » qui fournit rapidement les recherches de répertoires et les métadonnées. Cela me permet d'éviter les temps d'attente redondants lors du chargement et de l'analyse. En coordonnant ces deux niveaux, on obtient des gains de temps de réponse significatifs.

Tirer le meilleur parti du chargement automatique de Composer

L'autochargeur Composer est un moteur principal de résolution des chemins d'accès. Plus son fonctionnement est déterministe, plus la tâche du cache Realpath est facilitée.

  • Optimiser Classmap: composer dump-autoload -o réduit les analyses de répertoires et les recherches répétées.
  • Respecter strictement le chargement automatique: Avec classmap-authoritative (Configuration du projet) j'évite les solutions de repli inutiles qui, sinon, déclencheraient des résolutions de chemin supplémentaires.
  • Organiser la structure: Des hiérarchies de dossiers plates et cohérentes, ainsi qu'un nombre réduit de cas particuliers (par exemple, les inclusions inter-modules ou inter-mandants), permettent de stabiliser la charge du cache.

Résultat : moins de chemins différents par requête, une réutilisation accrue dans le cache Realpath et, par conséquent, une réduction des coûts d'E/S.

FPM et budget mémoire : quelles sont les valeurs réalistes par worker ?

Comme le cache Realpath existe pour chaque processus, la taille configurée est multipliée par le nombre de workers FPM. Je prévois donc un budget :

  • Exemple: 12 workers × 8 Mio = 96 Mio d'espace Realpath ; à cela s'ajoutent l'OPcache, le tas PHP et la surcharge liée aux extensions.
  • Équilibrer: Si OPcache dispose de suffisamment de mémoire, Realpath peut se voir attribuer quelques MiB supplémentaires – ou inversement.
  • Spécifique à la piscine: Les différents pools FPM (Front, Admin, API) peuvent avoir des tailles de Realpath différentes, en fonction de l'empreinte du code correspondant.

Si le code s'étoffe à chaque nouvelle version, le realpath_cache_size- Les besoins varient généralement. Je vérifie donc régulièrement le taux d'occupation maximal en condition de charge, et pas seulement en condition de repos.

Cas particuliers : liens symboliques, conteneurs et NFS

Lors des déploiements de liens symboliques, je rédige une brève TTL ou redémarrez FPM après le déploiement afin que tous les workers chargent les chemins d'accès mis à jour. Dans les conteneurs avec des volumes modifiables, je veille à ce que le cache ne contienne pas de données obsolètes Objectifs en ajustant la valeur TTL. Sur NFS, il est également recommandé d'adopter une stratégie OPcache bien pensée et de limiter au maximum les changements de répertoire. Si les chemins d'accès changent pendant l'exécution, je vide de manière ciblée, en cas de doute, avec clearstatcache(true) y compris la partie « Realpath ». Des règles de déploiement claires permettent d'éviter les incohérences entre les différents workers.

Obstacles et limites courants

Comme le cache est associé à chaque processus, chacun doit Travailleur Commencer par collecter les chemins d'accès avant que l'effet ne prenne effet. Dans les configurations soumises à des restrictions strictes d'open_basedir, le cache Realpath fonctionne de manière limitée ; c'est pourquoi j'en tiens compte. Frontières lors de la planification. Des caches trop petits entraînent du thrashing, tandis que des caches trop grands gaspillent de la mémoire vive : je cherche le point optimal à l’aide de mesures. Je tiens également à souligner que Realpath n’est pas un cache de métadonnées ou de contenu, mais qu’il stocke exclusivement des résolutions de chemins d’accès. Si l’on se fait de fausses idées à ce sujet, on risque de négliger des causes situées ailleurs.

Sécurité de fonctionnement : problèmes courants et vérifications rapides

Certains symptômes indiquent clairement des problèmes liés au Realpath – et peuvent être rapidement vérifiés :

  • Latences irrégulières après le déploiement: Soit un TTL trop long lors de la rotation des liens symboliques, soit un « warm-up » manquant. Solution : TTL court, redémarrage du FPM, puis « priming ».
  • De nombreuses répétitions stat()-vues: Avec strace visible ; souvent, la taille du cache est trop petite ou certains chemins dynamiques évincent les entrées fréquemment consultées.
  • Forte variance entre les workers: Caches différents selon les processus. Solution : un préchauffage cohérent et une répartition homogène des requêtes.

Un rapide bilan de santé via PHP suffit souvent :

<?php
$entries = realpath_cache_get();
$byDir = 0 ; $byFile = 0 ;
foreach ($entries as $e) { $e['is_dir'] ? $byDir++ : $byFile++ ; }
printf("Répertoires : %d, fichiers : %d, utilisé : %.2f MiB\n", $byDir, $byFile, realpath_cache_size()/1048576);

Cela me permet de voir si ce sont surtout les répertoires (nombreux modules, structures « vendor ») ou les fichiers (nombreux fichiers de configuration/classes) qui occupent la majeure partie du cache – et d’ajuster la structure ou la taille en conséquence.

Cache Stat vs. cache Realpath : une distinction à faire

Outre le cache Realpath, PHP gère également un Stat-Cache pour les résultats de stat() et les appels associés. Ces deux caches peuvent être gérés avec clearstatcache() influencer :

  • clearstatcache() vide le cache des statistiques (en option pour un fichier spécifique).
  • clearstatcache(true) vide également le cache Realpath.

Dans de rares cas – par exemple avec des workers CLI s'exécutant en continu et utilisant des montages dynamiques, ou lors de remplacements à chaud –, j'utilise une commande ciblée clearstatcache(true)- Hook après les modifications connues. Sinon, je laisse le TTL fonctionner et j'évite les invalidations inutiles.

Évaluation pratique des environnements d'hébergement

Je commence par déterminer la taille du projet, c'est-à-dire le nombre de fichiers chargés par une requête type, puis je vérifie la charge du Caches. Je choisis ensuite une valeur pour `realpath_cache_size` qui englobe tous les chemins fréquemment utilisés, avec une marge supplémentaire, et je définis un TTL adapté aux cadences de déploiement. Je surveille ensuite les effets à l'aide des outils de monitoring et des journaux, puis j'ajuste prudemment les valeurs, plutôt que de les augmenter de manière brutale. Il est également utile de se pencher sur le cache du système d’exploitation, par exemple sur le paramètre Linux Pression du cache VFS, car Realpath tire parti de recherches rapides dans les répertoires. Cela me permet d'apporter des améliorations sans négliger les effets secondaires.

Portée et chemins de configuration : où définir quelle valeur

Selon l'environnement, je gère ces paramètres à différents endroits :

  • Global: php.ini pour les paramètres par défaut à l'échelle du système.
  • Pro-Pool: Dans les pools FPM par php_admin_value[realpath_cache_size] et php_admin_value[realpath_cache_ttl] dimensionner de manière ciblée en fonction du front-end et de l'API.
  • Répertoire Pro: Dans .user.ini (si cela est autorisé), ce qui est utile dans les environnements d'hébergement mutualisé.

Important : les modifications apportées à la php.ini Les configurations de pool FPM nécessitent un redémarrage ou un rechargement pour que les workers démarrent avec les nouvelles valeurs.

CLI, Queue-Worker et tâches Cron : mêmes règles, durées d'exécution différentes

Les scripts CLI et les workers de file d'attente bénéficient également du cache Realpath – toutefois, la Durée de vie souvent différent :

  • Tâches CLI éphémères: Le cache est recréé à chaque appel. Dans ce cas, le temps de préchauffage et une valeur TTL élevée ne servent pas à grand-chose ; l'important est plutôt de disposer d'une taille suffisante pour que les inclusions répétées dans le job lui-même soient mises en cache.
  • Démons/Workers: Les processus qui s'exécutent en continu (Supervisor, Systemd) constituent un cache stable. Après un Rechargement du code (Déploiement) : le processus devrait redémarrer, sinon des chemins obsolètes pourraient rester dans le cache.

Évaluation de la taille des projets et effet de stockage

Une application comportant 4 000 chemins uniques d'une longueur de 80 octets chacun, plus 128 octets de surcharge par entrée, nécessite environ 832 Ko. Mémoire dans le cache Realpath ; je prévois 4 Mio ou plus, par mesure de sécurité. Si la base de code augmente considérablement en raison de plugins ou de modules, j'adapte la capacité de manière linéaire et je vérifie à nouveau la Hits par rapport aux échecs. Sur les hébergements mutualisés, je fais également attention aux limites d'inodes, car un trop grand nombre de petits fichiers peut surcharger l'ensemble du système ; cet aperçu m'aide à cet égard Limites d'inodes. Mieux vaut prévoir une marge de manœuvre plutôt que de fonctionner en permanence à la limite. Cela me permet d'économiser des appels système sans consommer inutilement de la mémoire vive.

En bref : mon programme de tuning

Je commence par compter le nombre de fichiers par requête, puis je définis une valeur appropriée Taille du cache et une solution adaptée à vos pratiques de déploiement TTL. Ensuite, je vérifie la charge à l'aide de realpath_cache_get()/size(), j'ajuste progressivement les paramètres et je combine le tout avec des réglages fins d'OPcache et du cache du système d'exploitation. Lors du déploiement de liens symboliques, je maintiens un TTL court ou je redémarre FPM ; dans les environnements statiques, j’utilise des durées de vie longues. L’objectif reste un taux de réussite élevé du cache sans gaspillage de RAM. C’est ainsi que je tire du cache Realpath un « turbo » sous-estimé pour des performances PHP constantes.

Derniers articles

Serveur doté d'une mémoire PHP Opcache visualisée pour l'analyse de la fragmentation
Administration

Détecter et corriger la fragmentation de l'Opcache PHP pour optimiser les performances

Apprenez à détecter la fragmentation de l'OPcache PHP, à y remédier grâce à la surveillance et à la configuration, et à optimiser les performances de vos applications grâce à un réglage ciblé de PHP. Thème principal : la fragmentation de l'OPcache PHP dans les environnements d'hébergement professionnels.

Visualisation d'un cache Redis avec des serveurs et des flux de données illustrant les politiques d'éviction LFU et LRU
Bases de données

Redis LFU vs LRU : quelle politique d'éviction choisir ?

Pour configurer ton cache de manière optimale, tu dois comprendre comment fonctionne l'éviction Redis avec les algorithmes LFU et LRU de Redis : cet article te propose une comparaison directe et t'aide à choisir la stratégie la plus adaptée.