Comportement du Query Cache de la base de données dans l'hébergement : optimisation pour de meilleures performances

J'explique comment le mysql query cache behavior dans les environnements d'hébergement modernes, pourquoi MySQL 8.0 a supprimé le Query Cache interne et comment devenir sensiblement plus rapide avec Redis ou Memcached. Je montre des leviers clairs pour Mise en cache des requêtes, Les sites web sont plus souvent livrés à partir de la mémoire cache et les bases de données fonctionnent moins bien.

Points centraux

  • MySQL 8.0: Supprimer le cache de requêtes interne et reprendre les caches externes.
  • En mémoireDonnées fréquemment lues en un clin d'œil à partir de la mémoire vive.
  • Invalidation: TTL, événements et versionnage contre les données obsolètes.
  • Suivi: le hit-ratio, la latence et les évictions contrôlent le tuning.
  • 300%Une mise en cache correcte réduit la charge et améliore les performances.

Comportement du cache de requêtes dans l'hébergement expliqué brièvement

Lorsque des demandes arrivent, je vérifie d'abord si le résultat est déjà dans le Cache se trouve. S'il se trouve là, je réponds sans accès à la base de données et j'économise de la latence ainsi que du temps CPU sur le Serveur de base de données. Si l'entrée manque, je crée le résultat, je le mets en cache et je le livre pour que la prochaine occurrence soit plus rapide et que la Temps de chargement des pages diminue. Je réduis ainsi le nombre de requêtes identiques et diminue la charge du serveur pour les accès récurrents à contenus populaires. Dans les configurations d'hébergement avec de nombreuses requêtes similaires (page d'accueil, listes de produits, structures de menus), le comportement du cache de requêtes apporte des avantages significatifs. Accélération.

De MySQL Query Cache à Redis/Memcached : la voie contemporaine

L'ancien MySQL Query Cache ralentissait lors de nombreux accès en écriture, c'est pourquoi MySQL 8.0 a supprimé le Fonction. Je mise plutôt sur Redis ou Memcached, car cela me permet de mettre en cache indépendamment de la Base de données et d'utiliser des clés granulaires, des TTL et des stratégies d'éviction. Cela me permet d'alléger sensiblement la charge de travail de MySQL, car les requêtes de lecture atteignent plus souvent l'élément de base. Cache en mémoire, MySQL se concentre sur les transactions réelles. Je garde les clés de cache délibérément petites, je les versionne lors des modifications et j'assure ainsi un haut niveau de sécurité. Taux de réussite. Cette approche fournit des réponses cohérentes en cas de forte charge de travail et s'adapte à de multiples Travailleur ou des conteneurs.

Pourquoi le cache de requêtes interne a-t-il vraiment été supprimé ? Il bloquait les systèmes fortement parallélisés par des verrous globaux, invalidait souvent des zones de table entières lors de modifications et causait beaucoup de surcharges administratives lors de charges de travail mixtes en lecture/écriture. Résultat : plus les accès en écriture sont nombreux, plus l'utilité est faible - jusqu'à freiner le réseau. Les caches modernes se trouvent donc en dehors de MySQL, utilisent des TTL isolés par clé, permettent une mise à l'échelle horizontale et peuvent être déployés indépendamment. MySQL lui-même continue à bénéficier du pool de tampons InnoDB, de bons index et d'instructions préparées - mais la mise en cache des résultats reste du ressort de la couche application.

Comprendre les niveaux de cache : en mémoire, base de données, application

Je distingue trois niveaux pour que le Mise en cache s'applique proprement : cache proche de l'application (Redis/Memcached), cache proche de la base de données (par ex. Buffer Pool) et caches HTTP/Reverse-Proxy. Je mets en cache des résultats de requêtes complets ou des données rendues Fragments, ce qui offre une flexibilité maximale. Près de la base de données, je profite d'index optimisés et de l'InnoDB Buffer Pool, qui contient les pages les plus lues dans la base de données. RAM ne s'arrête pas. Au niveau HTTP, je minimise les appels dynamiques lorsque le contenu est vraiment statique sont les mêmes. Je vous propose un aperçu rapide des tactiques dans le document compact Guide des stratégies de mise en cache, Le système de gestion de la qualité de l'entreprise est basé sur un système de gestion de la qualité qui facilite l'utilisation appropriée en fonction du scénario d'application.

Comparaison des modèles de mise en cache

Je choisis le modèle en fonction du risque, de la fréquence des changements et du besoin de cohérence :

  • Cache-Aside (chargement paresseux) : L'application vérifie la mémoire cache, charge à partir de la BD en cas de miss, écrit dans la mémoire cache. Simple, flexible, couplage faible - mais vulnérable aux stampedes à l'expiration du TTL.
  • Lecture à travers: Une couche de cache se charge automatiquement à partir de la source de données. Comportement uniforme, mais complexité supplémentaire dans la couche intermédiaire.
  • écriture directeChaque fois que l'on écrit, les données vont d'abord dans le cache, puis dans la base de données. Très cohérent, mais le chemin d'écriture s'allonge.
  • Write-BehindCache : reçoit les écritures et les transfère de manière asynchrone dans la BD. Rapide, mais délicat en cas de panne ; à n'utiliser qu'avec des garanties claires.
  • Stale-While-RevalidateLes entrées expirées peuvent être retournées brièvement „anciennes“ pendant qu'un job d'arrière-plan les remplit à nouveau. Idéal contre les pics de charge.

Validation de la mémoire cache sans erreur de données

Je planifie la validation du cache de manière à ce que les données actuelles aient toujours la priorité, et Rapidité reste en place. Je fixe le temps de vie (TTL) suffisamment court pour montrer les changements en temps réel, mais suffisamment long pour que les taux de réussite reste élevé. Lors des opérations d'écriture, je supprime des clés ciblées (Write-Through/Write-Behind) ou j'augmente une Version dans l'espace de noms des clés, afin que les accès suivants tirent l'enregistrement frais. Pour les contenus sensibles (prix, stocks, comptes), j'utilise des noms de domaine plus courts. TTL ou une invalidation immédiate après les mises à jour. J'évite ainsi les réponses obsolètes et maintiens la cohérence des données dans les systèmes distribués. Systèmes.

Éviter la débandade du cache : Stale-While-Revalidate, Locks et Jitter

Pour éviter le „problème du dogpile“, j'utilise des mécanismes combinés : une TTL doux, qui permet quelques secondes de „stale“ pendant qu'un single-flight-worker met à jour l'objet ; un court Mutex (par exemple via Redis SET NX + TTL) pour qu'un seul processus recharge ; et un Jitter sur les TTL (écart aléatoire), pour éviter que des milliers de clés n'expirent en même temps. En cas d'erreur sur la source d'origine, j'autorise stale-if-error et protège la base de données des avalanches.

Taille, TTL et Eviction : les bonnes vis de réglage

Je choisis la taille de la mémoire cache en fonction du volume de données qui en vaut la peine, en RAM de se situer. Trop petit augmente les miss, trop grand gaspille la mémoire, c'est pourquoi je mesure en continu et réagis aux Pics de charge. Pour Eviction, je préfère utiliser LRU si les modèles d'accès sont cycliques, et passer à LFU si les modèles d'accès sont clairs. Les succès durables. Je tiens les TTL de manière différenciée : navigation statique plus longue, disponibilité dynamique des produits plus court. Le tableau suivant montre des valeurs de départ typiques, que j'affine ensuite par monitoring et que j'adapte à des situations réelles. Utilisez à l'aide d'un logiciel.

Paramètres Objectif valeur initiale Grandeur de mesure
Taille de la mémoire cache Budget RAM pour les caches de requêtes ou de fragments 5-15% de la RAM du serveur Evictions/minute, utilisation de la RAM
TTL statique Menus, pages de catégories, listings fréquents 300-1800 secondes Hit-ratio, besoin d'actualité
TTL dynamique Prix, stock, personnalisation 10-120 secondes Taux d'erreur, corrections
Eviction LRU/LFU/FIFO par modèle d'accès LRU par défaut Taux de fraude, accès répétés
Schéma clé Versionnement contre les données obsolètes user:v1:queryhash Coup manqué après le déploiement

Je tiens également compte de la répartition des tailles d'objets et des limites supérieures. Je compresse les objets individuels dépassant par exemple 512 Ko ou je les divise en pages (pagination) afin que les évènements ne suppriment pas des blocs entiers de mégaoctets. Des caches différents (par ex. „hot“ et „cold“) avec des tailles séparées empêchent que quelques gros objets supplantent les nombreuses petites entrées fréquemment lues.

Conception et normalisation des clés

De bonnes clés déterminent le taux de réussite et d'invalidité. Je normalise les paramètres de la requête (tri, majuscules, valeurs par défaut), je convertis les listes dans un ordre canonique et je hache les paramètres longs dans un Hachage de la requête, pour que les clés restent courtes. Dans la clé, je sépare proprement les facettes : site:v3:fr-FR:category:42:page:2:filter:abc123. La personnalisation, le mandant, la devise, le local et la catégorie d'appareil sont visibles dans l'espace de noms. Je quantifie les paramètres numériques (par ex. les filtres de prix sont arrondis à des buckets raisonnables) afin d'éviter les doublons. Caches négatifs (p. ex. „pas de correspondance“) avec un TTL très court réduisent les accès à la BD en cas de répétitions Miss-Recherche.

Bien choisir la sérialisation et la compression

Je choisis les formats en fonction de l'interface et du budget de l'unité centrale : JSON est universel et lisible, MessagePack ou Protobuf économisent de la RAM/bande passante. Pour les objets de grande taille, j'utilise LZ4 ou Snappy pour une compression rapide ; Gzip uniquement si la taille maximale est plus importante que le CPU. Un Seuil (par ex. à partir de 4-8 Ko) évite que les petites données soient comprimées inutilement. Je veille à des schémas stables : si j'ajoute des champs, j'augmente la Version clé, pour que les anciens analyseurs syntaxiques ne se cassent pas.

Redis vs. Memcached : Différences de fonctionnement

Memcached marque des points avec une architecture simple, le multithreading et Slabs pour une allocation efficace. C'est le premier choix pour des résultats clés/valeurs très simples avec des QPS extrêmement élevés sans besoin de persistance. Redis offre des structures de données (hash, sets, sorted sets), un contrôle TTL fin, une réplication et une capacité de cluster. Pour les listes, les leaderboards, les compteurs et les Pub/Sub, Redis est idéal. En tant que cache de résultats pur, je désactive la persistance (ou je place des snapshots parcimonieux) afin d'économiser les E/S. J'utilise Pipeline et MGET, Je choisis la politique d'éviction en fonction du modèle d'accès (allkeys-lfu pour les clés permanentes, volatile-lru pour une utilisation TTL stricte). Je répartis les hot-keys par sharding/cluster ou je les réplique volontairement plusieurs fois pour atténuer les goulots d'étranglement.

Surveillance et réglage en cours de fonctionnement

J'observe les taux de réussite, la latence par opération de cache et le taux d'éviction afin de détecter les goulots d'étranglement. Si la latence augmente, je vérifie les chemins réseau, la saturation du processeur sérialisation d'objets, par exemple. J'abaisse les grands objets en les comprimant ou je les divise en plus petits afin de Mémoire de mieux l'utiliser. Si le hit ratio diminue, j'identifie les clés manquantes et j'ajuste les TTL ou les Schémas clés à. Le tuning reste un cycle de mesures, d'hypothèses, d'adaptations et de nouvelles Mesure.

Des indicateurs concrets aident à analyser les causes : keyspace_hits/-misses, evicted_keys, reclaimed (Memcached), used_memory et RSS-écarts pour la fragmentation, les latences P99 par commande, les taux d'erreur du réseau et les Slowlog-entrées dans la base de données. Je veille à ce que les évictions soient continues et non erratiques, à ce que la taille des objets soit uniformément répartie et à la proportion de „stale served“. Si miss→db→set se déroule plus souvent que prévu, soit le TTL n'est pas correct, soit les clés varient trop largement (absence de normalisation).

Sécurité et haute disponibilité

Je n'expose jamais publiquement les serveurs de cache, mais je les lie à des interfaces/VPC internes, j'active les ACLs et, si possible TLS. Je sépare strictement les environnements de production, de staging et de test, afin qu'aucune clé n'entre en conflit et qu'aucune donnée ne se déplace. Je bloque les opérations critiques (FLUSH*) à l'aide d'autorisations. Pour Basculement j'utilise la réplication et, selon la technologie, la commutation automatique (par exemple, chien de garde/ sentinelle/cluster). En tant que cache de résultats, la persistance est utilisée avec parcimonie ou pas du tout - si le cache tombe en panne, l'application peut être plus lente, mais correcte. Je limite les commandes qui analysent des espaces-clés entiers et je ne planifie des sauvegardes que là où le cache est également présent. Source de vérité est (rarement le cas).

WordPress et le commerce électronique : modèles et pièges typiques

Pour WordPress, je mets en cache les structures de menus, les résultats de requêtes WP_Query et les informations importantes. Widgets, tandis que j'exclue les parties personnalisées. Je fais attention à ce que les plugins n'envoient pas toutes les requêtes. contourner, en définissant des sessions ou en modifiant constamment les cookies. Pour les systèmes de boutique, je mets en cache les pages de catégories, les listes des meilleures ventes et les résultats des filtres avec une courte durée. TTL, tandis que les paniers d'achat et les pages de compte restent dynamiques. Celui qui mise sur l'ancien cache de requêtes détériore souvent la Performance; J'explique ici pourquoi il en est ainsi : WordPress Query Cache. C'est ainsi que je maintiens l'équilibre entre la vitesse et l'utilisation correcte de l'ordinateur. Personnalisation.

En outre, je varie les caches aux bons endroits : Monnaie, Langue, Site et Groupe de clients influencent les prix, les disponibilités et le contenu. Je dissocie la personnalisation du reste : la page sort du cache, seuls les petits blocs (par ex. le compte du panier) sont rechargés de manière dynamique. Pour les filtres très variables (facettes), je normalise l'ordre et crée des clés de page (page=1,2,...) au lieu de créer des clés énormes et encombrantes. Et je m'assure que les réponses „pas de résultat“ sont brièvement mises en cache afin de réduire les analyses de la base de données.

Planification des capacités et modèle de coûts

Je calcule d'abord grossièrement : la taille moyenne de l'objet × le nombre attendu de clés + l'overhead (10-30%) donne la Base de RAM. Exemple : 80 000 objets de 6 Ko chacun plus 25% de frais généraux ≈ 600 Mo. Pour la croissance, je prévois des tampons (par ex. 30-50%). Du côté du débit, j'estime le ratio lecture/écriture, la taille cible et le nombre de fichiers.taux de réussite (70-95%) et la décharge de la base de données qui en résulte. Si 60% des lectures de BD précédentes sont servies à partir du cache, non seulement la charge CPU et IOPS diminue, mais souvent aussi les Réplication-balises. J'évalue des scénarios : Augmenter le prix de la RAM, économiser les noyaux de la base de données - la plupart du temps, l'investissement en RAM est nettement gagnant car il permet d'obtenir des temps de réponse plus réguliers.

Penser ensemble le buffer pool InnoDB, le plan de requêtes et les index

Je n'optimise pas de manière isolée, mais je considère le cache, Pool de mémoire tampon, plan de requête et index sous forme de package. Un buffer pool bien dimensionné augmente les hits InnoDB, réduit les I/O et renforce chaque Cache à ce sujet. Je vérifie les requêtes lentes, je crée des index manquants et je tiens les statistiques à jour pour que l'Optimizer obtienne le meilleur résultat possible. Plan de l'école. Pour des étapes plus approfondies, ce Optimisation du buffer pool, que j'utilise parallèlement à la mise en cache. Ainsi, la vitesse s'additionne : moins d'E/S, plus d'occurrences de RAM et une meilleure efficacité. Requêtes.

En pratique, cela signifie que je dimensionne le buffer pool de manière à ce qu'il puisse contenir des pages de données „chaudes“ sans affamer le système d'exploitation. Les profils de requête révèlent si les scans de tables complètes, les JOINs sous-optimaux ou les index de couverture manquants contournent les caches. Je vérifie si des SELECT trop larges (colonnes inutiles) génèrent de gros objets en cache et je les élague. Si les requêtes varient fortement, je normalise les paramètres dans l'application ou je les ramène à quelques variantes réutilisables.

Utiliser correctement les ressources matérielles

Je réserve suffisamment de RAM pour Redis/Memcached et pour l'InnoDB Tampon pool pour que les disques durs ne bloquent presque pas. Je veille à ce que les cœurs de l'unité centrale permettent aux applications et au serveur de cache de fonctionner simultanément. travaillent peuvent être évitées. Les SSD NVMe réduisent la latence résiduelle lorsqu'une erreur de cache entraîne une perte de données. Mémoire s'applique. La latence du réseau reste importante, c'est pourquoi je place les serveurs de cache près des App ou dans le même hôte. Ces choix permettent souvent d'économiser des coûts d'hébergement en euros, car je peux utiliser moins de cœurs et des coûts d'hébergement plus faibles. Dernier les mêmes temps de réponse.

En outre, je tiens compte des topologies NUMA et Socket, j'épingle les processus sur les noyaux si nécessaire et j'utilise des chemins réseau courts (ou des sockets Unix sur le même hôte). Pour les configurations de conteneurs, je prévois des ressources „garanties“ afin que le cache ne soit pas étranglé et je prévois une marge de manœuvre pour les charges de pointe. Si les hot-keys sont inévitables, je répartis le trafic sur plusieurs réplicas ou je le route vers le cache le plus local afin d'éviter les latences inter-zones.

Déploiement, tests et échauffement du cache

Je teste les changements de mise en cache avec des profils de charge qui reflètent des données d'utilisation réelles. En production, je déploie par étapes (Canary), j'observe le hit ratio, les latences et la charge de la base de données avant d'augmenter les TTL. Lors des déploiements, j'augmente les Version clé et préchauffe les Top-N-Keys (page d'accueil, Topseller, catégories importantes). Les jobs d'arrière-plan remplissent les pages de listes et de détails de manière ciblée afin que les premiers utilisateurs ne supportent pas les coûts de préchauffage. Je simule des évictions (environnement de test) et stresse les hot-paths pour vérifier la protection contre le stampede et la gigue.

Plan pas à pas pour de meilleures performances d'hébergement

Je commence par faire le point : lent Requêtes, les fichiers journaux, le hit ratio, les évictions et les profils CPU/RAM. Ensuite, je définis des clés de cache pour les pages les plus importantes et j'établis des règles pour les autres pages. TTLs qui équilibrent l'actualité et la vitesse. J'intègre l'invalidation par écrit ou par événement pour les modifications afin que Consistance reste en place. Ensuite, je mesure à nouveau, j'augmente ou je diminue les TTL, j'adapte la taille du cache et je retire les Fugueurs avec des objets de grande taille. Pour finir, j'affine le buffer pool, les index et les plans jusqu'à ce que la livraison des pages soit perceptible. liquide est en cours.

En bref

Je remplace l'ancien cache de requêtes MySQL par Redis ou Memcached, je contrôle consciemment les clés, les TTL et les évictions et je garde les données fiables avec une invalidation claire. J'obtiens ainsi, selon l'application, 200-300% Vitesse, Surtout lorsque de nombreuses demandes identiques arrivent. Le monitoring guide mes décisions : Si le hit-ratio diminue ou si la latence augmente, j'adapte la taille, le TTL et le nombre de requêtes. Clé à l'avenir. Associée à un solide buffer pool InnoDB et à des index propres, la plateforme évolue mieux et réagit très bien. rapide. Comprendre le comportement de mysql query cache comme un système global permet d'économiser la charge du serveur, de réduire les coûts en euros et d'offrir aux utilisateurs une expérience croustillante. Expérience utilisateur.

Derniers articles