PHP OPcache accélère mes scripts, car PHP utilise le code compilé code octet en mémoire, ce qui évite un nouvel analyse syntaxique. Dans ce guide, je vais vous montrer comment j'utilise OPcache. configure, surveille et ajuste avec précision afin que votre application réagisse plus rapidement de manière mesurable et absorbe sereinement les pics de charge.
Points centraux
- Cache de bytecode réduit la charge CPU et les E/S
- Paramètres Comment sélectionner de manière ciblée memory_consumption et max_accelerated_files
- Environnements Réglage différencié : développement, mise en scène, production
- Suivi Utiliser pour le taux de réussite, l'occupation, les expulsions
- Déploiement et synchroniser proprement le cache flush
Voici comment fonctionne OPcache : bytecode au lieu de recompilation
À chaque requête, PHP lit généralement les fichiers, analyse le code et crée code octet, exécuté par le moteur Zend. C'est là qu'OPcache entre en jeu : il stocke ce bytecode dans la mémoire partagée afin que les requêtes suivantes puissent être lancées directement à partir de la mémoire. Cela réduit les cycles CPU et les accès aux fichiers, ce qui raccourcit considérablement les temps de réponse. Dans les configurations typiques, j'obtiens ainsi des gains compris entre 30 et 70 %, selon la base de code et le profil de trafic. Il est essentiel que le cache reste suffisamment grand et que les scripts les plus importants soient stockés en permanence dans le Mémoire rester.
Vérifier et activer OPcache sous Linux, Windows et hébergement mutualisé
Je commence toujours par consulter phpinfo() et rechercher „ Zend ». OPcache“ ainsi que des clés telles que opcache.enable ou opcache.memory_consumption. Sous Linux, j'active le module via le paquet php-opcache et un fichier opcache.ini dans le répertoire conf.d. Sous Windows, il suffit d'entrer zend_extension=opcache dans le fichier php.ini et de redémarrer le serveur web. En hébergement mutualisé, j'active souvent OPcache via un fichier php.ini personnalisé ou via le menu client. En cas de goulots d'étranglement, je vérifie également le Augmenter la limite de mémoire PHP, afin que OPcache et PHP-FPM disposent de suffisamment de Ressources reçu.
Les principaux commutateurs expliqués de manière compréhensible
Avec opcache.enable, j'active le cache pour les requêtes Web, tandis que opcache.enable_cli contrôle l'utilisation pour les tâches CLI, ce qui est utile pour les files d'attente de tâches. Le cœur est constitué par opcache.memory_consumption, qui spécifie la mémoire partagée disponible en mégaoctets ; une estimation trop juste entraîne des évictions et de nouvelles compilations. opcache.max_accelerated_files définit le nombre maximal de fichiers pouvant être placés dans le cache ; cette valeur doit dépasser de manière raisonnable le nombre de fichiers du projet. Avec opcache.validate_timestamps et opcache.revalidate_freq, je détermine le niveau de rigueur avec lequel OPcache vérifie les modifications apportées aux fichiers, de très dynamique (développement) à très économe (production avec vidage manuel). Je sauvegarde les commentaires avec opcache.save_comments=1, car de nombreux outils utilisent DocBlocks dépendants.
Comparaison des valeurs initiales et des profils
Pour un démarrage sans heurts, je mise sur des profils clairs pour le développement, la mise en scène et la production. Cela me permet d'obtenir d'une part des cycles de rétroaction rapides lors du codage et d'autre part des performances fiables en fonctionnement réel. Il est important de vérifier régulièrement ces valeurs de départ par rapport à des mesures réelles et de les affiner. Pour les installations WordPress plus importantes, je prévois une mémoire et des entrées généreuses, car les plugins et les thèmes nécessitent beaucoup de ressources. Fichiers . Le tableau suivant récapitule les valeurs de départ pertinentes, que j'ajuste ensuite en fonction du taux de réussite et des évictions.
| Réglage | Développement | Mise en scène/Test | Production |
|---|---|---|---|
| opcache.enable | 1 | 1 | 1 |
| opcache.enable_cli | 0 | 0-1 | 1 (pour les tâches CLI) |
| opcache.memory_consumption | 128 à 256 Mo | 256 à 512 Mo | 256–512+ Mo |
| opcache.interned_strings_buffer | 16 à 32 Mo | 32 à 64 Mo | 16 à 64 Mo |
| opcache.max_accelerated_files | 8 000–10 000 | 10 000–20 000 | 10 000–20 000+ |
| opcache.validate_timestamps | 1 | 1 | 0–1 (selon Deploy) |
| opcache.revalidate_freq | 0–2 s | 60 à 300 s | 300+ s ou 0 (avec vérification manuelle) |
| opcache.save_comments | 1 | 1 | 1 |
| opcache.fast_shutdown | 1 | 1 | 1 |
Cette matrice est volontairement pragmatique, car les projets réels évoluent de manière très différente. Je commence avec ces valeurs, puis j'observe le taux de réussite, la part occupée dans la mémoire partagée et l'apparition d'évictions. En cas de signes de pression, j'augmente d'abord opcache.memory_consumption par étapes modérées. Ensuite, j'ajuste opcache.max_accelerated_files jusqu'à ce que le nombre de fichiers s'y intègre confortablement. Ainsi, le Cache efficace et les demandes restent régulières.
Paramètres par environnement : développement, mise en scène, production
Dans le développement, il est important d'obtenir rapidement des retours sur les modifications apportées au code. C'est pourquoi je définis validate_timestamps=1 et revalidate_freq à une valeur très faible, voire à 0. Lors de la mise en scène, je vérifie la charge réaliste et définis une mémoire généreuse afin que les résultats se rapprochent du fonctionnement réel ultérieur. En production, j'augmente la fréquence de vérification ou je désactive complètement les horodatages si mon déploiement vide ensuite le cache de manière ciblée. Pour les workers basés sur CLI, j'active enable_cli=1 afin que les tâches récurrentes soient également exécutées par le Cache de bytecode . Ainsi, chaque environnement génère exactement le comportement dont j'ai besoin, sans surprise au niveau des temps de réaction.
Les paramètres avancés qui font souvent la différence
Au-delà des paramètres de base, il existe des commutateurs qui me permettent d'augmenter la stabilité et la sécurité et de minimiser les effets secondaires :
- opcache.max_wasted_percentage : définit à partir de quel degré de fragmentation OPcache déclenche une reconstruction interne de la mémoire. En cas de bases de code très variables, je réduis légèrement cette valeur afin d'avoir moins de mémoire „ fragmentée “.
- opcache.force_restart_timeout : délai en secondes après lequel OPcache effectue un redémarrage forcé lorsqu'un redémarrage est nécessaire, mais que des processus sont encore actifs. Cela permet d'éviter les états d'incertitude prolongés.
- opcache.file_update_protection : fenêtre de protection en secondes pendant laquelle les fichiers récemment modifiés ne sont pas immédiatement mis en cache. Cela permet d'éviter les fichiers à moitié écrits pendant les déploiements ou sur les lecteurs réseau.
- opcache.restrict_api : limite les scripts autorisés à appeler opcache_reset() et les fonctions d'état. En production, je le configure de manière stricte afin que seuls les points de terminaison d'administration y aient accès.
- opcache.blacklist_filename : fichier dans lequel je conserve les modèles qui sont exclus du cache (par exemple, les générateurs hautement dynamiques). Cela permet d'économiser de l'espace pour des scripts plus critiques.
- opcache.validate_permission et opcache.validate_root : actifs lorsque plusieurs utilisateurs/chroots sont en jeu. PHP empêche ainsi l'utilisation non autorisée du code mis en cache d'un contexte dans un autre.
- opcache.use_cwd et opcache.revalidate_path : contrôle de la manière dont OPcache identifie les scripts lorsque les chemins d'accès sont intégrés via différents répertoires de travail/liens symboliques. Dans le cas des liens symboliques de publication, je teste ces valeurs de manière ciblée afin d'éviter les doubles caches.
- opcache.cache_id : lorsque plusieurs hôtes virtuels partagent le même SHM (ce qui est rare), je sépare clairement les caches à l'aide d'un identifiant unique.
- opcache.optimization_level : je laisse généralement ce paramètre sur la valeur par défaut. Je ne réduis temporairement les passes d'optimisation que dans les cas limites de débogage.
Préchargement : conserver une partie du code en permanence en mémoire
Avec PHP 7.4+, je peux charger et lier des fichiers de framework ou de projet centraux au démarrage du serveur via opcache.preload et opcache.preload_user. L'avantage : les classes sont disponibles sans autoload hits et les hot paths sont immédiatement disponibles. Quelques règles pratiques :
- Le préchargement est particulièrement utile pour les bases de code volumineuses et stables (par exemple Symfony, bibliothèques principales propres). Avec WordPress, je l'utilise avec parcimonie, car le cœur et les plugins sont mis à jour plus fréquemment.
- Un fichier de préchargement contient des appels opcache_compile_file() ciblés ou intègre un autochargeur qui charge les classes définies. à l'avance charge.
- Toute modification du code des fichiers concernés par le préchargement nécessite un redémarrage de PHP-FPM afin que le préchargement soit reconstruit. J'intègre cela dans les déploiements.
- Je mesure l'effet séparément : tous les codes n'en bénéficient pas ; le préchargement consomme davantage de mémoire partagée.
JIT et OPcache : avantages, limites, besoins en mémoire
Depuis PHP 8, il existe un compilateur juste-à-temps (JIT) contrôlé par OPcache (opcache.jit, opcache.jit_buffer_size). Pour les charges de travail web typiques avec des charges d'E/S et de base de données, le JIT n'apporte souvent que peu d'avantages. Pour les codes très gourmands en CPU (par exemple, le traitement d'images/de données), il peut être d'une aide notable. Voici comment je procède :
- J'active JIT de manière conservatrice et mesure les métriques des utilisateurs réels ainsi que les profils CPU. Une activation aveugle augmente les besoins en mémoire et peut déclencher des cas limites.
- Je dimensionne la mémoire tampon JIT en fonction des routes gourmandes en ressources CPU. Les tampons trop petits n'apportent aucune valeur ajoutée, tandis que les tampons trop grands supplantent le bytecode.
- Si le taux de réussite ou l'occupation SHM en pâtit, je privilégie OPcache plutôt que JIT. Le cache bytecode est le levier le plus important pour la plupart des sites.
Chemins d'accès aux fichiers, liens symboliques et stratégies de déploiement sécurisées
OPcache est basé sur les chemins d'accès. C'est pourquoi je me concentre sur la stratégie de déploiement :
- Versions Atomic via symlink (par exemple /releases/123 -> /current) : propre, mais attention au comportement de opcache.use_cwd et realpath. J'évite les caches en double en faisant en sorte que tous les workers voient systématiquement le même chemin réel.
- Avec validate_timestamps=0, le cache doit partout Vider : après la commutation, je vide OPcache de manière ciblée sur tous les hôtes/pods et je relance PHP-FPM de manière contrôlée.
- Je synchronise realpath_cache_size et realpath_cache_ttl avec OPcache afin que les recherches de fichiers restent rapides et stables.
- Sur les lecteurs réseau (NFS/SMB), j'augmente file_update_protection et je configure les déploiements de manière à ce que les fichiers soient remplacés de manière atomique.
Pour des redémarrages très rapides, j'utilise souvent une procédure en deux étapes : d'abord un échauffement en arrière-plan, puis un rechargement court et coordonné de tous les workers, afin que le premier trafic en direct trouve déjà un cache chaud.
Cache de fichiers, préchauffage et amorçage
En plus de la mémoire partagée, OPcache peut éventuellement écrire le bytecode sur le disque (opcache.file_cache). Cela peut être utile dans certains cas particuliers :
- Dans les environnements conteneurisés, un cache de fichiers peut entre Réduire les temps de recompilation lors des redémarrages FPM, à condition que le stockage soit rapide.
- J'utilise opcache.file_cache avec prudence : sur les systèmes de fichiers lents ou distribués, cela n'apporte pas grand-chose et augmente la complexité.
- opcache.file_cache_only est un cas particulier pour les environnements sans SHM – peu utilisé pour les configurations axées sur les performances.
Pour les échauffements, je me construis de petits „ primers “ :
- Un script CLI appelle opcache_compile_file() pour les fichiers chauds, par exemple les autochargeurs, les classes centrales du framework, les grands assistants.
- Un robot d'indexation visite les pages les plus importantes (page d'accueil, connexion, paiement) afin que le bytecode et les caches en aval soient prêts à temps.
- Je synchronise les préchauffages de manière à ce qu'ils soient terminés juste avant le changement de version.
OPcache dans la pile : PHP-FPM, cache d'objets et cache de pages
OPcache montre toute sa puissance lorsqu'il est associé à PHP-FPM, à une configuration de processus propre et à des couches de cache supplémentaires. Avec WordPress, je le combine avec un cache objet (tel que Redis) et un cache de page afin de soulager la base de données et le rendu. Pour cela, je veille à ce que Performances mono-thread, car les requêtes PHP dépendent fortement des différents cœurs de processeur. Si une pression survient malgré tout, je répartis la charge via PHP-FPM-Worker, sans choisir une mémoire partagée trop petite pour OPcache. J'utilise ainsi le Pile complètement, au lieu de simplement tourner une vis de réglage.
Erreurs fréquentes et vérifications rapides
Une mémoire cache trop petite entraîne des évictions, que je peux détecter dans l'état OPcache ou phpinfo(). Si cela se produit, j'augmente progressivement opcache.memory_consumption et je vérifie l'effet sur le taux de réussite. Si les fichiers ne sont pas accélérés, je règle opcache.max_accelerated_files à une valeur supérieure à la quantité réelle de fichiers dans le projet. En cas de problèmes de déploiement, je vérifie validate_timestamps : avec 0, l'ancien bytecode reste actif jusqu'à ce que je vide explicitement le cache. Des outils tels que Doctrine exigent des DocBlocks, c'est pourquoi je laisse save_comments=1 pour Erreur en évitant les annotations manquantes.
Surveiller et interpréter OPcache
Je mesure le taux d'accès et vise en permanence des valeurs proches de 100 %, afin que les requêtes soient presque toujours lancées à partir du cache. De plus, je surveille l'utilisation de la mémoire et le nombre d'évictions afin de détecter rapidement les goulots d'étranglement. Avec opcache_get_status(), je crée de petits tableaux de bord ou j'alimente des solutions de surveillance existantes. Cela me permet de voir immédiatement les changements après les versions ou les mises à jour de plugins. Grâce à ces métriques, je prends des décisions éclairées. Décisions et n'adapte que ce qui est vraiment nécessaire.
Des lignes directrices concrètes qui ont fait leurs preuves :
- Taux de réussite > 99 % sous charge normale et maximale ; en dessous, je vérifie la répartition des fichiers et le préchauffage.
- Part libre SHM constante > 5–10 % ; sinon, je redimensionne la mémoire.
- Évictions au fil du temps : des pics ponctuels après le déploiement sont acceptables ; des évictions continues indiquent un sous-dimensionnement ou une forte fragmentation.
- Garder un œil sur la mémoire gaspillée : si elle atteint la limite, je prévois une reconstruction contrôlée de l'OPcache (par exemple pendant les fenêtres de maintenance).
Exemple : configuration WordPress avec un trafic élevé
Pour les grands sites WordPress, je choisis opcache.enable=1 et opcache.enable_cli=1 afin que les CLI Workers puissent également en bénéficier. Je règle volontiers la mémoire partagée sur 384 Mo ou plus lorsque de nombreux plugins et un thème riche en fonctionnalités sont impliqués. J'augmente opcache.interned_strings_buffer à 64 Mo, car de nombreux noms de classes et de fonctions reviennent dans toutes les requêtes. Pour les environnements extrêmement performants, je définis validate_timestamps=0 et revalidate_freq=0, mais je vide le cache directement après chaque publication. Il est important de concevoir les déploiements de manière à ce qu'aucun ancien code octet reste en circulation.
Flux de travail pratique pour le réglage et les déploiements
Je travaille selon des cycles fixes : mesurer, modifier, contrôler. Je commence par enregistrer les valeurs d'état telles que le taux de réussite, l'occupation et les évictions, puis j'ajuste un paramètre et je mesure à nouveau. Avant une mise en production, je supprime l'OPcache de manière ciblée avec les horodatages désactivés, soit via un redémarrage PHP-FPM, soit via un petit script. Je contrôle ensuite les pics de charge avec du trafic réel ou des benchmarks représentatifs. Si un comportement inhabituel apparaît, je vérifie également Fragmentation de la mémoire, car ils réduisent l'espace utilisable Partagé La mémoire diminue.
Quelques routines supplémentaires qui ont fait leurs preuves au sein des équipes :
- Versionner les modifications des paramètres : opcache.ini dans le dépôt, modifications via Pull Request et Changelog.
- Canary Deploys : seule une partie des workers/pods télécharge les nouvelles versions et crée un cache, puis le déploiement s'effectue sur toutes les instances.
- Bouton d'urgence : un point de terminaison administratif interne avec accès sécurisé qui permet les appels opcache_reset() et opcache_invalidate() ciblés, combiné avec opcache.restrict_api.
- Estimer l'ordre de grandeur : en règle générale, je calcule initialement 1 à 2 Mo d'OPcache pour 100 à 200 fichiers PHP, puis j'ajuste ensuite en fonction des métriques réelles. Pour WordPress avec de nombreux plugins, j'ajoute une marge.
En bref
OPcache accélère les applications PHP en compilant le code octet dans la mémoire vive. En choisissant les bons paramètres pour la mémoire, le nombre de fichiers et la stratégie d'horodatage, vous obtiendrez des temps de réponse toujours courts. Veillez à la coordination avec PHP-FPM et les autres couches de cache afin que l'ensemble de la pile fonctionne correctement. Surveillez le taux de réussite, l'occupation et les évictions afin de pouvoir effectuer des ajustements ciblés. Vous garantirez ainsi des performances et une fiabilité optimales. Plate-forme pour charges élevées et croissance importante.


