78 votes

Qu'est-ce que la mise en cache ?

J'entends constamment parler d'une personne qui a rencontré un problème de performance x qu'elle a résolu grâce à la mise en cache.

Ou comment le fait de faire x, y, z dans le code de vos programmes peut nuire à votre capacité de mise en cache.

Même dans l'un des derniers podcasts, Jeff Atwood explique comment ils mettent en cache certaines valeurs pour les retrouver plus rapidement.

Il semble qu'il y ait une certaine ambiguïté dans les termes "cache" et "mise en cache" et cela m'a conduit à être confus quant à leur signification dans différents cas. Je ne sais pas si vous faites référence à la mise en cache des applications ou des bases de données, au cpu, etc. et ce que cela signifie.

Qu'est-ce que la mise en cache et quels en sont les différents types ?

D'après le contexte, je peux en avoir une idée, pour stocker une valeur souvent récupérée dans dans la mémoire principale et d'y avoir d'y accéder rapidement. Cependant, qu'est-ce que c'est ? vraiment ?

Ce mot semble être utilisé dans de nombreux contextes différents avec des significations légèrement différentes (cpu, base de données, application, etc.) et je cherche vraiment à le clarifier.

Y a-t-il une distinction entre le fonctionnement de la mise en cache dans vos applications et la mise en cache dans votre base de données ?

Quand quelqu'un dit qu'il a trouvé un un morceau de code qui nuisait à la mise en cache et qu'après l'avoir corrigé, il a amélioré la vitesse de leur application, de quoi de quoi parle-t-il ?

La mise en cache du programme est-elle quelque chose qui se fait automatiquement ? Comment pouvez-vous autorisez vous la mise en cache des valeurs dans vos programmes ? J'ai souvent lu des utilisateurs sur ce site dire qu'ils ont mis en cache une valeur dans leur application, je suis assis ici et je et je me demande ce qu'ils veulent dire.

Aussi, qu'est-ce que cela signifie vraiment quand quelqu'un parle de base de données de base de données ? Est-ce simplement une fonction qu'ils activent dans leur base de données ? Est-ce que devez-vous mettre explicitement les valeurs en cache ou ou la base de données choisit-elle celles qui seront cache pour vous ?

Comment puis-je commencer à mettre moi-même en cache des éléments pour améliorer les performances ?

Pouvez-vous me donner quelques exemples de la façon dont je peux commencer à mettre en cache des valeurs dans mon applications ? Ou encore, est-ce quelque chose qui est déjà fait, sous le capot, et je dois simplement écrire mon code d'une manière particulière pour permettre la "mise en cache" ?

Qu'en est-il de la mise en cache de la base de données, comment puis-je commencer ? J'ai entendu parler de choses comme memcache. Ce type d'utilitaire est-il nécessaire pour la mise en cache dans les bases de données ?

Je cherche à obtenir une bonne distinction entre la mise en cache dans les applications par rapport aux bases de données, comment elles sont utilisées et comment elle est mise en œuvre dans les deux cas.

6 votes

Si vous votez pour la fermeture, veuillez en donner la raison.

6 votes

C'est une question parfaitement acceptable. La personne qui veut la fermer a tort. +1

63voto

cletus Points 276888

La mise en cache est une pratique qui consiste à stocker et à récupérer des données dans une mémoire haute performance (généralement la mémoire), de manière explicite ou implicite.

Je m'explique. L'accès à la mémoire est plus rapide que celui à un fichier, à une URL distante (en général), à une base de données ou à tout autre stockage externe d'informations. Donc si l'acte d'utiliser une de ces ressources externes est important alors vous pouvez bénéficier de la mise en cache pour améliorer les performances.

Knuth a dit un jour que l'optimisation prématurée est la racine de tous les maux. Eh bien, la mise en cache prématurée est la Racine de tous les maux de tête en ce qui me concerne. Ne résolvez pas un problème avant d'avoir ont un problème. Chaque décision que vous prenez a un coût que vous paierez pour la mettre en œuvre maintenant et que vous paierez à nouveau pour la modifier plus tard. Donc, plus vous repousserez le moment de prendre une décision et de modifier votre système, mieux ce sera.

Alors d'abord identifier que vous avez réellement un problème et où il se situe . Le profilage, la journalisation et d'autres formes de tests de performance vous aideront ici. Je ne saurais trop insister sur l'importance de cette étape. Le nombre de fois où j'ai vu des gens "optimiser" quelque chose qui n'était pas un problème est stupéfiant.

Ok, donc vous avez un problème de performance. Disons que vos pages exécutent une requête qui prend beaucoup de temps. Si c'est une lecture, vous avez un certain nombre d'options :

  • Exécutez la requête en tant que processus distinct et placez le résultat dans un cache. Toutes les pages accèdent simplement au cache. Vous pouvez mettre à jour la version en cache aussi souvent que nécessaire (une fois par jour, une fois par semaine, une fois toutes les 5 secondes, selon ce qui convient) ;
  • Cachez de manière transparente via votre fournisseur de persistance, ORM ou autre. Bien sûr, cela dépend de la technologie que vous utilisez. Hibernate et Ibatis, par exemple, prennent en charge la mise en cache des résultats des requêtes ;
  • Demandez à vos pages d'exécuter la requête si le résultat n'est pas dans le cache (ou s'il est "périmé", ce qui signifie qu'il a été calculé il y a plus longtemps que l'"âge" spécifié) et de le mettre dans le cache. Cela pose des problèmes de concurrence si deux processus distincts (ou plus) décident tous qu'ils doivent mettre à jour le résultat, de sorte que vous finissez par exécuter la même requête (coûteuse) huit fois à la fois. Vous pouvez gérer ce problème en verrouillant le cache, mais cela crée un autre problème de performance. Vous pouvez également vous rabattre sur les méthodes de concurrence de votre langage (par exemple, les API de concurrence de Java 5).

S'il s'agit d'une mise à jour (ou si des mises à jour ont lieu et doivent être reflétées dans votre cache de lecture), c'est un peu plus compliqué car il n'est pas bon d'avoir une ancienne valeur dans le cache et une valeur plus récente dans la base de données, de sorte que vous fournissez à vos pages une vue incohérente des données. Mais en gros, il y a quatre approches possibles :

  • Mettez à jour le cache, puis mettez en file d'attente une demande de mise à jour du magasin concerné ;
  • l'écriture par la mise en cache : le fournisseur de cache peut fournir un mécanisme permettant de faire persister la mise à jour et de bloquer l'appelant jusqu'à ce que cette modification soit effectuée ; et
  • Write-behind caching : même chose que write-through caching mais sans bloquer l'appelant. La mise à jour se fait de manière asynchrone et séparée ; et
  • Modèles de persistance en tant que service : cela suppose que votre mécanisme de mise en cache prend en charge une certaine forme d'observabilité (c'est-à-dire des écouteurs d'événements de cache). Fondamentalement, un processus entièrement séparé - inconnu de l'appelant - écoute les mises à jour du cache et les persiste si nécessaire.

La méthode que vous choisirez dépendra en grande partie de vos besoins, des technologies que vous utilisez et d'un grand nombre d'autres facteurs (par exemple, la mise en grappe et le basculement sont-ils nécessaires ?)

Il est difficile d'être plus précis que ça et de vous donner des conseils sur ce qu'il faut faire sans savoir beaucoup plus de détails sur votre problème (comme si vous aviez ou non un problème).

0 votes

Je sais que nous ne devrions mettre en cache que les ressources les plus demandées ou les plus occupées, mais ce sont elles qui occupent le plus d'espace et si je les mets en cache, pourquoi devrais-je les stocker dans la base de données ? Juste parce que je ne peux pas faire confiance aux données en mémoire pour rester éternellement Je suis toujours confus quant à l'utilité du cache, c'est bien qu'un serveur redis servira plus rapidement que mysql, alors pourquoi devrais-je avoir MYSQL si je vais stocker presque tout dans redis

1 votes

Qu'entendez-vous par "mise en cache transparente" et qu'est-ce qu'un "fournisseur de persistance" ?

0 votes

" Ne résolvez pas un problème avant d'avoir un problème. " --ANALYSE--

17voto

cdonner Points 17403

Vous lirez très probablement des articles sur la mise en cache dans le contexte des applications Web. En raison de la nature du Web, la mise en cache peut faire une grande différence en termes de performances.

Considérez ce qui suit :

Une demande de page web arrive au serveur web, qui transmet la demande au serveur d'application, qui exécute du code pour rendre la page, qui doit se tourner vers la base de données pour récupérer dynamiquement des données.

Ce modèle n'est pas très évolutif, car à mesure que le nombre de demandes de pages augmente, le serveur doit refaire la même chose pour chaque demande.

Cela devient encore plus problématique si le serveur web, le serveur d'applications et la base de données sont sur des matériels différents et communiquent entre eux par le réseau.

Si vous avez un grand nombre d'utilisateurs qui consultent cette page, il est logique de ne pas aller jusqu'à la base de données pour chaque demande. Au lieu de cela, vous avez recours à la mise en cache à différents niveaux.

Cache des résultats

La mise en cache des résultats consiste à stocker les résultats d'une requête de base de données avec la requête dans l'application. Chaque fois qu'une page Web génère une requête, l'application vérifie si les résultats sont déjà mis en cache et, si c'est le cas, elle les extrait d'un ensemble de données en mémoire. L'application doit encore rendre la page.

Cache des composants

Une page Web est constituée de différents composants - des pagelets, ou tout autre nom que vous voudrez bien leur donner. Une stratégie de mise en cache des composants doit savoir quels paramètres ont été utilisés pour demander le composant. Par exemple, une petite barre "Dernières nouvelles" sur le site utilise l'emplacement géographique ou la préférence de l'utilisateur pour afficher les nouvelles locales. Par conséquent, si les actualités d'un lieu sont mises en cache, le composant n'a pas besoin d'être rendu et peut être extrait du cache.

Cache de la page

Une stratégie de mise en cache de pages entières consiste à stocker la chaîne de requête et/ou les paramètres d'en-tête avec le HTML entièrement rendu. Le système de fichiers est suffisamment rapide pour cela - il est toujours beaucoup moins coûteux pour un serveur web de lire un fichier que d'appeler le serveur d'application pour obtenir le rendu de la page. Dans ce cas, chaque utilisateur qui envoie la même chaîne de requête obtiendra le même contenu en cache.

La combinaison intelligente de ces stratégies de mise en cache est le seul moyen de créer des applications Web réellement évolutives pour un grand nombre d'utilisateurs simultanés. Comme vous pouvez le constater, le risque potentiel est que si un élément de contenu dans le cache ne peut pas être identifié de manière unique par sa clé, les utilisateurs commenceront à voir le mauvais contenu. Cela peut devenir assez compliqué, en particulier lorsque les utilisateurs ont des sessions et qu'il existe un contexte de sécurité.

5voto

ChrisW Points 37322

Il y a deux significations que je connais.


L'un est mise en cache des applications . En effet, si les données sont lentes à obtenir (par exemple, via le réseau) ou à calculer, l'application met en cache une copie des données (de sorte qu'elle n'a pas besoin de les obtenir à nouveau ou de les recalculer : elles sont déjà en cache). La mise en œuvre d'un cache nécessite un peu de logiciel d'application supplémentaire (logique pour utiliser le cache) et de la mémoire supplémentaire (dans laquelle stocker les données en cache).

C'est le "caching" qui est utilisé comme vous le citez ici :

Le contexte me permet de comprendre qu'il s'agit de stocker une valeur souvent récupérée dans la mémoire principale et d'y avoir un accès rapide.


Un autre est Mise en cache du CPU qui est décrit dans cet article de Wikipedia . La mise en cache par le CPU se fait automatiquement. Si vous lisez beaucoup à partir d'une petite quantité de mémoire, le CPU peut effectuer la plupart de ces lectures à partir de son cache. Par contre, si vous lisez à partir d'une grande quantité de mémoire, tout ne peut pas tenir dans le cache et le CPU doit passer plus de temps à travailler avec la mémoire plus lente.

C'est le "caching" qui est utilisé comme vous le citez ici :

Quand quelqu'un dit qu'il a trouvé un morceau de code qui nuit à la mise en cache et qu'après l'avoir corrigé, il a amélioré la vitesse de son application, de quoi parle-t-il ?

Ça veut dire qu'ils ont trouvé un moyen de réarranger leur code pour causer moins de Cache manqués .


Quant à mise en cache de la base de données Je ne sais pas.

4voto

Will Hartung Points 57465

Il y a quelques problèmes.

La première est la granularité. Votre application peut avoir des niveaux très fins de mise en cache en plus de ce que fait la base de données. Par exemple, la base de données est susceptible de mettre simplement en cache des pages de données, pas nécessairement des lignes spécifiques.

Une autre chose est que l'application peut stocker les données dans son format "natif", alors que la base de données ne met évidemment en cache que son format interne.

Un exemple simple.

Disons que vous avez un utilisateur dans la base de données, qui est composé de colonnes : USERID , FIRSTNAME , LASTNAME . Très simple.

Vous souhaitez charger un utilisateur, USERID=123 dans votre application. Quelles sont les étapes à suivre ?

  1. Lancement de l'appel de la base de données
  2. Analyse de la requête( SELECT * FROM USER WHERE USERID = ? )
  3. Planification de la demande (c'est-à-dire comment le système va-t-il aller chercher les données).
  4. Récupérer les données du disque
  5. Streaming des données de la base de données vers l'application
  6. Conversion des données de la base de données en données d'application (c.-à-d. USERID en un nombre entier, disons, les noms en Strings.

Le cache de la base de données mettra probablement en cache les étapes 2 et 3 (il s'agit d'un cache d'instructions, il n'analysera pas la requête et ne la réanalysera pas), et mettra en cache les blocs de disque réels.

Donc, voici la clé. Votre utilisateur, USER ID 123 nom JESSE JAMES . Vous pouvez voir que ce n'est pas beaucoup de données. Mais la base de données met en cache des blocs de disque. Vous avez le bloc d'index (avec l'icône 123 ), puis le bloc de données (avec les données proprement dites, et toutes les autres lignes qui tiennent sur ce bloc). Ainsi, ce qui représente nominalement, disons, 60-70 octets de données a en fait un impact sur la mise en cache et les données de la BD de, probablement, 4K-16K (en fonction de la taille du bloc).

Le bon côté des choses ? Si vous avez besoin d'une autre rangée à proximité (par ex. USER ID = 124 ), il y a de fortes chances que l'index et les données soient déjà mis en cache.

Mais même avec cette mise en cache, vous devez toujours payer le coût du déplacement des données sur le fil (et c'est toujours sur le fil, sauf si vous utilisez une base de données locale, alors c'est un bouclage), et vous "désarchivez" les données. C'est-à-dire que vous les convertissez de bits de base de données en bits de langage, puis en bits d'application.

Maintenant, une fois que l'application a obtenu son USER ID 123 il place la valeur dans une carte de hachage de longue durée.

Si l'application en a besoin à nouveau, elle cherchera dans la carte locale, le cache de l'application, et économisera les coûts de recherche, de transport par fil et de mise en forme.

Le côté obscur de la mise en cache des applications est la synchronisation. Si quelqu'un vient et fait un UPDATE USER SET LASTNAME="SMITH" WHERE USERID=123 votre application ne le sait pas et le cache est donc sale.

Il y a donc un tas de détails à gérer dans cette relation pour que l'application reste synchronisée avec la base de données.

Disposer d'une grande quantité de cache de base de données est très utile pour les grandes requêtes sur un ensemble de données "chaudes". Plus vous avez de mémoire, plus vous pouvez avoir de données "chaudes". Si vous pouvez mettre en cache l'intégralité de la base de données en RAM, vous éliminez le délai d'E/S (au moins pour les lectures) lié au déplacement des données du disque vers un tampon RAM. Mais vous avez toujours les coûts de transport et de mise en mémoire.

L'application peut être beaucoup plus sélective, par exemple en mettant en cache des sous-ensembles de données plus limités (les bases de données ne mettent en cache que des blocs), et le fait d'avoir les données "plus proches" de l'application permet d'obtenir de bien meilleures performances.

L'inconvénient est que tout n'est pas mis en cache dans l'application. La base de données a tendance à stocker les données plus efficacement, globalement, que l'application. Vous ne disposez pas non plus d'un langage de "requête" contre les données mises en cache dans l'application. La plupart des gens se contentent de mettre en cache une simple clé et de partir de là. Facile à trouver USER ID 123 plus difficile pour "TOUS LES UTILISATEURS NOMMÉS JESSE".

La mise en cache de la base de données a tendance à être "gratuite", vous définissez un nombre de tampons et le SGBD s'occupe du reste. Faible impact, réduit les délais globaux d'E/S et de disque.

La mise en cache des applications est, en fait, spécifique aux applications.

Cela fonctionne très bien pour les données "statiques" isolées. C'est très facile. Chargez un tas de choses dans des tables de consultation au démarrage et redémarrez l'application si elles changent. C'est facile à faire.

Après cela, la complexité commence à augmenter à mesure que l'on ajoute la logique "sale", etc.

En fin de compte, tant que vous disposez d'une API de données, vous pouvez mettre en cache de manière incrémentielle.

Donc, tant que vous appelez getUser(123) partout plutôt que d'atteindre la base de données, vous pouvez revenir plus tard et ajouter la mise en cache à getUser sans impacter votre code.

C'est pourquoi je suggère toujours une sorte de couche d'accès aux données dans le code de chacun, afin de fournir cette couche d'abstraction et d'interception.

0 votes

Que voulez-vous dire par "la mise en cache de la base de données a tendance à être "gratuite", " , et à quoi ressemblerait une couche d'accès aux données "en code", en gros ? en php ou express par exemple.

1 votes

Je veux dire "gratuit" en termes d'effort de la part du développeur de l'application. Le développeur bénéficie de toutes les capacités de mise en cache "gratuitement", puisqu'il n'a pas à modifier son code pour en tirer parti. Je ne peux pas parler de PHP ou d'Express, car je ne les connais pas.

0 votes

Compris, merci. Donc, dans la plupart des cas, la mise en cache est intégrée dans la base de données et automatique dans une certaine mesure ?

2voto

Gregor Brandt Points 5645

La mise en cache consiste à prendre le résultat d'un algorithme long ou gourmand en ressources informatiques et à sauvegarder la réponse de sorte que vous n'ayez pas à exécuter l'algorithme à nouveau, vous réutilisez simplement le résultat.

0 votes

Quel est le processus de mise en place de la mise en cache, et combien de temps prend-il ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X