...

Comprendre le cache de pages sous Linux : des performances accrues grâce au cache

Page Linux Je considère le cache comme un levier direct permettant d'accélérer l'accès aux fichiers, car il effectue les lectures répétées à partir de la mémoire vive (RAM) plutôt qu'à partir d'un support de stockage plus lent. Je vais vous montrer concrètement comment le noyau réduit ainsi les latences, accélère les charges de travail telles que les serveurs web, les bases de données et WordPress, et comment j'exploite cet effet à l'aide de moyens simples.

Points centraux

Les idées clés suivantes m'aident à Cache de la page les évaluer et les exploiter de manière ciblée.

  • mémoire cache RAM: Les données des fichiers sont stockées en mémoire, ce qui accélère les accès.
  • Réévaluation à la hausse: Les opérations d'écriture sont regroupées de manière plus efficace sous forme de „ pages sales “.
  • Transparence: Les applications en bénéficient sans modification du code.
  • Dynamique: Le cache libère de la mémoire lorsque cela est nécessaire.
  • Charges de travail: Le Web, les bases de données, le CI/CD et les journaux enregistrent une progression notable.

Qu'est-ce que le cache de page Linux ?

Je comprends le Cache de la page en tant qu'espace mémoire dans la RAM où le noyau stocke des blocs de fichiers dès que des processus utilisent read(), write() ou mmap() accéder aux fichiers. À chaque accès, le noyau vérifie d’abord le cache et fournit immédiatement les données depuis la mémoire si elles y sont déjà présentes, ce qui réduit sensiblement le temps de réponse. Si les données ne se trouvent pas dans le cache, le noyau les charge depuis le support de stockage, les y stocke et les met à la disposition du processus, ce qui permet un accès rapide lors de la prochaine requête. Ce mécanisme est étroitement lié au système de fichiers virtuel (Virtual File System) et s'exécute de manière transparente pour les applications, ce qui rend son utilisation universelle. De ce mode de fonctionnement découle un principe simple : j'utilise la mémoire RAM libre comme Surface du cache au lieu de le laisser inutilisé.

Pourquoi le cache de pages accélère sensiblement le chargement

L'effet le plus marqué s'explique par le fait que je E/S disque réduit considérablement dès que les données récurrentes se trouvent dans le cache et n'ont plus besoin d'être relues à partir du support de stockage. Les accès en lecture s'effectuent alors à partir de la mémoire vive (RAM), ce qui réduit considérablement les latences et les files d'attente au niveau des contrôleurs. Les opérations d’écriture en bénéficient également, car le noyau marque les modifications comme des „ pages sales “, les regroupe dans le temps et les écrit ensuite efficacement sur le support. Ainsi, de nombreux petits accès individuels, qui solliciteraient le stockage, disparaissent au profit d’un nombre réduit d’opérations plus importantes. Au final, après une brève phase de préchauffage, le système donne l’impression d’être plus rapide, car davantage de données de travail se trouvent dans le Mémoire restent.

Lecture, écriture, « Dirty Pages » : voici comment ça fonctionne

Un accès en lecture commence toujours par une vérification du cache, ce qui me permet d'obtenir des „ hits “ sans temps d'attente et de ne payer qu'une seule fois pour les « misses ». Lors d'une écriture, le contenu modifié est d'abord stocké dans la RAM et mis en attente en tant que « dirty » jusqu'à ce que le noyau le transfère de manière groupée vers le support de stockage. Si je le souhaite, je peux forcer l’enregistrement définitif avec fsync(), ce qui reste important lorsque les données Consistance dont j'ai besoin immédiatement. Ce chemin de réécriture améliore l'efficacité des applications qui manipulent de nombreux petits fichiers, comme le code PHP, les fichiers de configuration ou les ressources. En même temps, je garde à l'esprit que la réécriture améliore les performances, mais qu'il existe un court laps de temps pendant lequel tout n'est pas encore physiquement sauvegardé.

La mémoire vive libre correspond au cache – ce n'est pas une perte

Beaucoup considèrent la mémoire „ occupée “ avec scepticisme, mais j'interprète correctement cette valeur en considérant la part „ buff/cache “ comme un indicateur pertinent mémoire tampon valeurs. Le noyau utilise activement la mémoire RAM inutilisée, la restitue aux processus en un clin d'œil si nécessaire et gère l'équilibre grâce à des mécanismes de récupération. Cette dynamique garantit la réactivité de mon système tant qu'il y a suffisamment de données actives dans le cache. Si les besoins d’une application augmentent, le noyau évince les anciennes pages du cache et libère de l’espace sans que j’aie à intervenir manuellement. Lorsque j’entre dans des phases de forte charge, j’observe cela en me concentrant sur Pression du réservoir, afin d'évaluer correctement la situation et de cerner les goulots d'étranglement.

Les charges de travail qui en tirent un grand bénéfice

Je vois les principaux avantages dans tous les cas où les données reviennent souvent et où il y a de nombreuses petites consultations, ce qui Cache simplifiée. Les exemples classiques sont les serveurs Web contenant des fichiers PHP et HTML fréquemment utilisés, ainsi que les installations WordPress comportant des thèmes, des plugins, des médias et des configurations récurrents. Les bases de données tirent profit des requêtes répétées au niveau du système de fichiers, à condition qu’elles ne contournent pas délibérément le cache de page. Les systèmes CI/CD avec des artefacts de build, ainsi que les outils qui traitent de nombreux petits fichiers, gagnent également en vitesse de manière notable. Même les analyses de journaux, qui effectuent une lecture séquentielle, bénéficient d’un avantage grâce aux tampons RAM, car le noyau mémorise les modèles d’accès et les fournit plus rapidement.

Suivi et mesure : voici comment j'évalue les effets de cache

Je commence par vérifier avec free -h, quelle est la taille de „ buff/cache “ et comment occupé La mémoire s'est développée au fil du temps. Un aperçu de /proc/meminfo me montre des indicateurs tels que En cache, Sale et Writeback, qui fournissent des informations sur les lectures en cours et les opérations d'écriture en attente. Avec iostat -x 1 ou pidstat -d 1 Je constate si la charge d'E/S physique diminue dès que mon cache est « réchauffé ». Des outils tels que parfait ou bccLes scripts basés sur [...], bien qu'ils permettent d'approfondir l'analyse, sont rarement nécessaires au quotidien lorsque des schémas clairs se dégagent. De plus, je vérifie, en effectuant plusieurs accès au fichier, si la deuxième exécution est nettement plus rapide, ce qui met en évidence l'effet du Caches confirmé.

Réglages : paramètres et valeurs par défaut recommandées

Je ne modifie que ce que je comprends, et je commence l'optimisation du cache par quelques réglages simples et faciles à comprendre Vis de réglage. Les paramètres vm.dirty déterminent à partir de quel moment les opérations d'écriture sont transférées de la mémoire vive vers le support de stockage, ainsi que l'intensité avec laquelle ce processus s'effectue. vm.vfs_cache_pressure Détermine l'intensité avec laquelle le noyau remplace les caches Dentry et Inode, ce qui influe directement sur les opérations du système de fichiers. Les valeurs de prélecture au niveau des périphériques bloc peuvent améliorer les performances de lecture séquentielle lorsque les charges de travail en tirent profit. Je documente chaque étape, effectue des tests sous charge et, si nécessaire, je reviens aux valeurs par défaut si aucun gain n'est constaté.

Paramètres Standard Effet Quand modifier
vm.dirty_background_ratio 10% Début de la phase de réécriture asynchrone En cas de nombreuses petites écritures, déclencher le flush plus tôt
vm.dirty_ratio 20% Pourcentage maximal de „ dirty “ dans la mémoire vive (RAM) En cas de charge en rafale, augmenter la marge de sécurité
vm.dirty_expire_centisecs 3000 Temps de „ dirty “ jusqu'au flush (en 1/100 s) Pour les cibles de latence, régler sur une valeur plus faible
vm.dirty_writeback_centisec 500 Intervalle pour la réécriture en arrière-plan Si le stockage est lent, augmenter légèrement la charge
vm.vfs_cache_pressure 100 Besoin de libérer des dentries/inodes Réduire lors de nombreuses opérations sur les fichiers
Lecture anticipée par blocs selon l'appareil Aperçu séquentiel Augmenter lors des lectures en continu

Pour mieux comprendre les processus de récupération et de transfert, il est intéressant de se pencher sur Éviction du cache de pages, afin d'évaluer de manière approfondie sa propre configuration. J'apporte toujours les modifications par étapes, j'effectue des mesures et je documente clairement les effets, afin que chaque Adaptation reste compréhensible.

Cache de page et bases de données : quand est-il judicieux de les contourner ?

Certaines bases de données utilisent délibérément E/S directes afin d'éviter la mise en mémoire tampon double et d'utiliser leurs propres caches. Dans de tels scénarios, je travaille avec les paramètres internes de la base de données et je compte moins sur le cache de pages Linux. Si un moteur accède fréquemment à de nouvelles données ou à des volumes de travail très importants, le modèle de contournement est intéressant pour mieux maîtriser la consommation de mémoire. En revanche, si l’accent est mis sur des lectures répétées de fichiers provenant des mêmes tables ou index, le cache du système de fichiers reste utile. Je prends ma décision en fonction du profil d’accès réel, et non sur la base d’une règle générale, afin que la Performance augmente réellement.

Éviction, récupération et pression de mémoire

En cas de charge élevée, le noyau classe les pages en deux catégories : actives et inactives Listes LRU et supprime progressivement les candidats du cache. Ce processus de récupération réagit à la pression résultant d'une demande croissante des processus, des limites imposées par les cgroups ou des temps d'attente d'E/S. Si mon système de surveillance détecte une augmentation des évictions parallèlement à une hausse de la charge d’E/S, j’en conclus que l’ensemble de données de travail est plus volumineux que la mémoire vive disponible. Dans de telles situations, j’évalue s’il convient d’isoler certaines charges de travail, de modifier les stratégies de mise en cache ou d’augmenter la capacité de mémoire. Pour mieux comprendre les règles de libération de mémoire, je m'appuie sur un guide structuré traitant des Pression du réservoir, afin d'interpréter correctement les symptômes et de prévoir les mesures à prendre.

En pratique : vérifications rapides et commandes

Pour donner une première impression, je commence par free -h et lis la partie mémoire tampon/cache, avant d'aller plus loin. Ensuite, je compare deux exécutions d'une analyse de fichier, par exemple avec trouver ou un benchmark, et observe la différence de temps entre le démarrage à froid et le démarrage à chaud. grep -E "Cached|Dirty|Writeback" /proc/meminfo me montre la quantité de données stockées dans le cache et ce qui reste à écrire. iostat -xz 1 révèle le niveau d'utilisation des appareils et indique si la file d'attente diminue dès que la mise en cache entre en action. Si vous souhaitez en savoir plus sur les principes de base de la mise en cache, vous trouverez un aperçu dans Mise en cache du système de fichiers une introduction accessible qui explique l'interaction entre le VFS et la mémoire tampon RAM.

Dissiper les malentendus courants

„ La mémoire RAM est pleine, le serveur a un problème “, j'entends souvent cela, mais le Cache C'est là la réponse, pas la cause. Linux libère la mémoire de manière flexible lorsque les applications l'utilisent, et la réutilise dès que de nouvelles données y sont mises en cache. Le vidage manuel via echo 3 > /proc/sys/vm/drop_caches apporte rarement un bénéfice durable et fausse les mesures. Il est plus judicieux d’identifier les véritables goulots d’étranglement et d’alléger la charge sur les chemins d’E/S à ces endroits. Je fais également la distinction entre le cache de pages et les caches « slab » pour les dentries/inodes, afin de ne pas avoir deux Mécanismes je les mets dans une casserole.

Options de montage et subtilités du système de fichiers

Je tiens compte du fait que les options du système de fichiers et de montage ont une forte incidence sur l'efficacité du cache de pages. atime- Les mises à jour génèrent des écritures supplémentaires ; avec relatime (ce qui est aujourd'hui la norme), je les réduis, noatime Je fais encore plus d'économies si je ne suis jamais tributaire des horaires d'accès. sync et dirsync Ils imposent une persistance immédiate et annulent les avantages du « write-back » – ce qui est justifié pour les métadonnées pour lesquelles la latence est critique, mais sinon, je les évite. Modes de journalisation (par exemple avec ext4 data=ordonné vs. writeback) déterminent si les données utiles sont stockées sur le support avant ou après les métadonnées ; je privilégie la sécurité à une performance illusoire. XFS et btrfs se comportent différemment en matière de métadonnées et de CoW : le CoW, la compression ou la déduplication permettent d'économiser des E/S, mais peuvent solliciter le processeur. Je mesure donc les charges de travail de manière réaliste et je décide si les options de montage correspondent au profil d'accès.

Conteneurs, machines virtuelles et caches dupliqués

Dans les conteneurs, tous les processus partagent le même noyau – et donc également le même cache de pages. Cela facilite le partage des fichiers fréquemment utilisés (par exemple, les bibliothèques), mais des limites strictes imposées par les cgroups (memory.max) peuvent évincer prématurément les pages mises en cache. Je prévois une marge par service et j'utilise memory.low, afin d'offrir une certaine protection aux caches importants. Dans les machines virtuelles, il existe deux Caches : dans le client et, le cas échéant, chez l’hôte (pour les sauvegardes de fichiers). Cela entraîne une mise en mémoire tampon double. Si j’utilise des périphériques bruts ou le stockage direct, j’évite le cache de l’hôte, mais je perds ses avantages. Le ballooning et l’overcommit influencent la récupération de mémoire dans l’invité : je surveille si un ballooning constant entraîne un cache thrashing, et j’ajuste les ressources ou le dimensionnement en conséquence. Avec le stockage en conteneurs (OverlayFS), je préchauffe de manière ciblée les couches fréquemment utilisées afin que les déploiements ne démarrent pas à froid.

NUMA, cgroups et isolation

Sur les systèmes NUMA, le noyau gère des listes LRU par nœud. Si les threads effectuent principalement des accès locaux, les coups de cache de page numa-nah et réduisons la latence. Grâce à l'affinité CPU et mémoire, je veille à ce qu'une application et ses données soient proches les unes des autres. Via memcg (cgroups v2), le cache de pages est attribué à un groupe ; avec memory.high je déclenche une récupération contrôlée, avec memory.max je fixe des limites strictes et avec memory.low Je donne la priorité aux services importants. Ces outils permettent d'éviter qu'une tâche batch bruyante ne vide le cache d'un service web sensible à la latence. L'isolation facilite la planification, mais je veille à trouver un équilibre afin d'éviter la création d'un trop grand nombre de petits caches qui, pris individuellement, n'enregistrent pas suffisamment de succès.

SSD, HDD et la lecture anticipée en pratique

Le readahead est un atout pour les accès séquentiels, mais souvent un simple frein pour les accès aléatoires. Sur les disques durs (HDD), j’augmente généralement le readahead afin d’accélérer les balayages linéaires. Sur les SSD NVMe rapides, l’avantage est moindre ; un readahead trop important gaspille de la mémoire vive (RAM) et réduit le taux de réussite du cache, car les pages inutilisées évincent les autres. J’ajuste la prélecture pour chaque périphérique et je vérifie, à l’aide de tests répétés, si le débit ou les latences s’en trouvent améliorés. Je tiens également compte du planificateur d’E/S : pour les disques NVMe, „ none “/„ mq-deadline “ est courant, tandis que les disques durs peuvent bénéficier d’un planificateur de type « deadline ». Le cache de pages lisse les profils d’E/S, mais la couche de blocs doit s’y adapter. L’objectif reste que le cache contienne principalement des données utiles et réutilisées – et non pas simplement des octets préchargés.

Démarrages à froid, préchauffage et déploiements

Chaque cache a besoin d'une phase de préchauffage. Après un redémarrage ou un déploiement, je lis de manière ciblée les hotsets, par exemple en parcourant une fois de manière séquentielle les répertoires importants. Cela réduit sensiblement le „ temps de démarrage “ après les déploiements. Dans le cadre de stratégies de déploiement progressif, je maintiens au moins une instance « chaude » en ligne afin que le service global réponde rapidement pendant que les nouvelles instances remplissent leur cache. J’évite les modifications massives de l’arborescence des fichiers (par exemple, les changements de chemins d’accès), car cela « refroidit » les dentries/inodes. Je préfère utiliser des changements de liens symboliques atomiques ou des stratégies de « copy-on-write », dans lesquelles le contenu des fichiers et les chemins d’accès restent largement stables. Ainsi, non seulement le cache de pages reste efficace, mais les caches de métadonnées conservent également leur efficacité.

Paramètres de mesure en profondeur

En plus de /proc/meminfo pour établir un diagnostic précis, je jette un œil à /proc/vmstat: des compteurs tels que pgfault et pgmajfault distinguent les « page faults » légères des « page faults » graves, nr_active_file/nr_inactive_file indiquent la taille du jeu de travail basé sur les fichiers, et workingset_refault permet de détecter le « thrashing ». Si le nombre de « refaults » augmente alors que le débit d'E/S de l'appareil reste élevé, cela signifie que le bloc de travail ne tient pas dans la RAM. Je réalise mes tests en effectuant deux exécutions de la même charge de travail : la deuxième exécution devrait être nettement plus rapide si le cache est efficace. Pour garantir la reproductibilité des tests de démarrage à froid, je vide les caches exclusivement en environnement de laboratoire et je documente soigneusement cette opération afin de ne pas fausser les mesures en production. Il est important pour moi de ne pas surinterpréter un indicateur isolé, mais plutôt d’identifier des tendances à travers des séries chronologiques.

Éviter le swap, le « swappiness » et le « thrashing »

Sous pression, Linux vide d'abord le cache de pages avant de se tourner vers les pages anonymes – tant que cela reste judicieux. Lorsque la mémoire vive vient à manquer pour les processus et que les pages anonymes ne sont pas suffisamment disponibles, le système commence à utiliser la mémoire de pagination. Une trop faible Le « swappiness » peut entraîner une gestion trop agressive de la mémoire anonyme importante (heaps/stacks) et, par conséquent, l'éviction de pages de cache utiles, ce qui augmente les opérations d'E/S. Une trop élevée À l'inverse, une valeur trop élevée de « Swappiness » entraîne un transfert plus précoce vers le disque et des pics de latence. Je choisis des valeurs modérées, je mesure et j'observe : l'objectif est que mon « hotset » reste en mémoire vive et que seules les données « froides », rarement utilisées, soient transférées vers le disque au détriment de la mémoire swap – jamais les données « chaudes ».

Sécurité et pérennité : les données sur le support

La réécriture en mémoire vive améliore les performances, mais crée une brève période pendant laquelle les modifications ne sont stockées qu'en mémoire vive. Pour les données qui doivent être conservées immédiatement, j'utilise fsync() ou fdatasync(). Je m'en tiens également à des paramètres par défaut sûrs, tels que les barrières d'écriture et la journalisation ; j'évite les options risquées qui désactivent ces barrières. Au niveau du stockage, je prête attention aux caches des contrôleurs : les politiques de réécriture différée (write-back) avec batterie de secours ou condensateur sont rapides et sûres, tandis que les caches non sécurisés sans protection sont risqués. À l'échelle du système, je force sync le vidage de toutes les données – un outil rudimentaire que j'utilise à bon escient et rarement. Je combine ainsi la rapidité offerte par le cache de page avec une persistance propre là où elle est essentielle à l'activité.

WordPress et les piles web : astuces pratiques

Dans la pile Web, les caches s'additionnent : le cache de pages Linux accélère les ressources statiques, les fichiers PHP et les configurations, tandis qu'un cache OpCode PHP conserve le chemin d'exécution et le bytecode en mémoire. Je veille à ce que les déploiements ne modifient pas constamment le chemin d'accès au code et je réduis les accès aux fichiers en regroupant les ressources. Une couche de cache d'objets persistante réduit les E/S de la base de données, ce qui permet au cache du système de fichiers de gérer encore plus efficacement les fichiers « chauds » restants. Dans la mesure du possible, je ne stocke pas les sessions et les données transitoires sur le disque local, mais dans des caches en mémoire ou en réseau, afin que le cache de page puisse exploiter pleinement ses atouts pour les autres fichiers fréquemment consultés. Résultat : moins d’E/S physiques, des réponses plus rapides et des latences plus stables.

En bref

Le cache de pages Linux me fournit des réponses rapides concernant les fichiers RAM et réduit considérablement les accès coûteux au support de données. Les « Lesehits » accélèrent les applications, tandis que le « Write-back » regroupe de nombreuses écritures individuelles et améliore l'efficacité. La mémoire libre n'est pas laissée inoccupée, mais sert de cache pour une plateforme réactive. Avec des indicateurs tels que free -h, /proc/meminfo et iostat je perçois l'effet avant même de prendre en compte des paramètres tels que vm.dirty_ratio ou vm.vfs_cache_pressure allez-y. Ceux qui connaissent bien les charges de travail, testent les modifications de manière contrôlée et utilisent le cache de façon ciblée obtiennent une amélioration sensible Performance sans modification du code.

Derniers articles