


L'implémentation Java garantit la cohérence de la double écriture entre le cache et la base de données
Tutoriel de base Javala colonne assure la cohérence de la double écriture entre cache et base de données
S'il vous plaît, relevez la tête, ma princesse, sinon la couronne tombera.
Le cache distribué est un composant indispensable dans de nombreuses applications distribuées. Cependant, lors de l'utilisation du cache distribué, cela peut impliquer un double stockage et une double écriture du cache et de la base de données. Il y a certainement des problèmes de cohérence des données, alors comment résoudre le problème de cohérence ?
Modèle Cache Aside
Le mode de mise en cache + lecture et écriture de base de données le plus classique est le modèle Cache Aside.
Lors de la lecture, lisez d'abord le cache. S'il n'y a pas de cache, lisez la base de données, puis retirez les données et mettez-les dans le cache, et renvoyez la réponse en même temps.
Lors de la mise à jour, mettez d'abord à jour la base de données, puis supprimez le cache.
Pourquoi supprimer le cache au lieu de mettre à jour le cache ?
La raison est très simple. Dans de nombreux cas, dans des scénarios de mise en cache complexes, le cache n'est pas seulement la valeur extraite directement de la base de données.
Par exemple, un champ d'une certaine table peut être mis à jour, puis le cache correspondant doit interroger les données des deux autres tables et effectuer des opérations pour calculer la dernière valeur du cache.
De plus, le coût de mise à jour du cache est parfois très élevé. Cela signifie-t-il qu'à chaque fois que la base de données est modifiée, le cache correspondant doit être mis à jour ? Cela peut être le cas dans certains scénarios, mais pour les scénarios de calcul de données mises en cache plus complexes, ce n'est pas le cas. Si vous modifiez fréquemment plusieurs tables impliquées dans un cache, le cache sera également mis à jour fréquemment. Mais la question est : ce cache sera-t-il fréquemment consulté ?
Par exemple, si un champ d'une table impliqué dans un cache est modifié 20 fois ou 100 fois en 1 minute, alors le cache sera mis à jour 20 fois ou 100 fois mais ce cache ne sera mis à jour que 20 fois ; fois ou 100 fois en 1 minute. Il a été lu une fois et contient beaucoup de données froides. En fait, si vous supprimez simplement le cache, le cache ne sera recalculé qu'une fois toutes les 1 minute et la surcharge sera considérablement réduite. Le cache n'est utilisé que pour calculer le cache.
En fait, supprimer le cache au lieu de mettre à jour le cache est une idée de calcul paresseuse. Ne refaites pas des calculs complexes à chaque fois, qu'il soit utilisé ou non, mais laissez-le être utilisé quand vous en avez besoin. à utiliser. Recalculez à nouveau. Comme mybatis et hibernate, ils ont tous l'idée du chargement paresseux. Lors de l'interrogation d'un service, le service apporte une liste d'employés. Il n'est pas nécessaire de dire qu'à chaque fois que vous interrogez le service, les données des 1 000 employés qu'il contient seront également trouvées en même temps. Dans 80% des cas, la vérification de ce service nécessite uniquement l'accès aux informations de ce service. Vérifiez d'abord le département, et en même temps vous devez accéder aux employés à l'intérieur. Ensuite, seulement lorsque vous souhaitez accéder aux employés à l'intérieur, vous interrogerez la base de données pour 1 000 employés.
Le problème et la solution d'incohérence du cache le plus élémentaire
Problème : modifiez d'abord la base de données, puis supprimez le cache. Si la suppression du cache échoue, de nouvelles données seront ajoutées dans la base de données et d'anciennes données dans le cache, ce qui entraînera une incohérence des données.
Solution : Supprimez d'abord le cache, puis modifiez la base de données. Si la modification de la base de données échoue, cela signifie qu'il y a d'anciennes données dans la base de données et que le cache est vide, les données ne seront donc pas incohérentes. Comme il n'y a pas de cache lors de la lecture, les anciennes données de la base de données sont lues puis mises à jour dans le cache.
Analyse des problèmes d'incohérence des données plus complexes
Les données ont changé, supprimez d'abord le cache, puis modifiez la base de données, mais elle n'a pas encore été modifiée. Lorsqu'une requête arrive, je lis le cache et constate que le cache est vide. J'interroge la base de données et trouve les anciennes données avant modification et les mets dans le cache. Ensuite, le programme de changement de données termine la modification de la base de données.
C'est fini, les données dans la base de données et dans le cache sont différentes. . .
Pourquoi le cache rencontre-t-il ce problème dans un scénario à forte concurrence avec des centaines de millions de trafic ?
Ce problème ne peut se produire que lorsqu'une donnée est lue et écrite simultanément. En fait, si votre simultanéité est très faible, en particulier si la simultanéité de lecture est très faible, avec seulement 10 000 visites par jour, alors dans de rares cas, le scénario incohérent que nous venons de décrire se produira. Mais le problème est que s'il y a des centaines de millions de trafic chaque jour et des dizaines de milliers de lectures simultanées par seconde, tant qu'il y a des demandes de mise à jour des données chaque seconde, l'incohérence base de données + cache mentionnée ci-dessus peut se produire.
La solution est la suivante :
Lors de la mise à jour des données, acheminez l'opération en fonction de l'identifiant unique des données et envoyez-la vers une file d'attente interne de jvm. Lors de la lecture des données, s'il s'avère que les données ne sont pas dans le cache, les données seront relues + le cache sera mis à jour Après routage selon l'identifiant unique, elles seront également envoyées dans la même file d'attente interne de jvm. .
Une file d'attente correspond à un thread de travail. Chaque thread de travail récupère les opérations correspondantes en série puis les exécute une par une. Dans ce cas, pour une opération de modification de données, le cache est d'abord supprimé puis la base de données est mise à jour, mais la mise à jour n'est pas encore terminée. À ce moment-là, si une demande de lecture arrive et que le cache vide est lu, la demande de mise à jour du cache peut d'abord être envoyée à la file d'attente. À ce moment-là, elle sera en retard dans la file d'attente, puis attendra de manière synchrone que la mise à jour du cache soit effectuée. complété.
Il y a un point d'optimisation ici. Dans une file d'attente, cela n'a aucun sens d'enchaîner plusieurs demandes de mise à jour du cache, donc un filtrage peut être effectué s'il s'avère qu'il y a déjà une demande de mise à jour du cache dans la file d'attente. file d'attente, alors il n'est pas nécessaire d'insérer une autre opération de demande de mise à jour, attendez simplement que la demande d'opération de mise à jour précédente soit terminée.
Une fois que le thread de travail correspondant à cette file d'attente a terminé la modification de la base de données pour l'opération précédente, il effectuera l'opération suivante, qui est l'opération de mise à jour du cache. À ce moment, la dernière valeur sera lue. la base de données, puis écrivez dans le cache.
Si la demande est toujours dans la plage de temps d'attente et qu'une interrogation continue révèle que la valeur peut être obtenue, elle reviendra directement si la demande attend plus d'une certaine période de temps, alors cette fois ; la valeur actuelle sera lue directement à partir de l’ancienne valeur de la base de données.
Dans les scénarios à forte concurrence, les problèmes auxquels il faut prêter attention avec cette solution :
1. Les demandes de lecture sont bloquées pendant une longue période
Parce que les demandes de lecture sont bloquées pendant une longue période. très légèrement asynchrone, nous devons donc faire attention au problème du délai de lecture. Chaque demande de lecture doit être renvoyée dans le délai d'expiration.
Le plus gros point de risque de cette solution est que les données peuvent être mises à jour très fréquemment, ce qui entraîne un important retard dans les opérations de mise à jour dans la file d'attente, puis un grand nombre de délais d'attente se produiront pour les demandes de lecture, et enfin un grand nombre de demandes seront traitées directement dans la base de données. Assurez-vous d'exécuter des tests simulés en situation réelle pour voir à quelle fréquence les données sont mises à jour.
Un autre point, car il peut y avoir un retard dans les opérations de mise à jour pour plusieurs éléments de données dans une file d'attente, vous devez le tester en fonction de vos propres conditions commerciales. Vous devrez peut-être déployer plusieurs services, et chaque service le fera. partager certaines données. Si une file d'attente mémoire compresse réellement les opérations de modification d'inventaire de 100 produits et que chaque opération de modification d'inventaire prend 10 ms, alors la demande de lecture du dernier produit peut attendre 10 * 100 = 1 000 ms = 1 s avant que les données puissent être obtenues. cette fois, cela entraînera un blocage à long terme des demandes de lecture.
Assurez-vous d'effectuer des tests de résistance et de simuler l'environnement en ligne en fonction du fonctionnement réel du système d'entreprise pour voir combien d'opérations de mise à jour peuvent être insérées dans la file d'attente mémoire pendant les périodes les plus chargées, ce qui peut conduire à Comment combien de temps la demande de lecture correspondant à la dernière opération de mise à jour se bloquera-t-elle ? Si la demande de lecture revient dans 200 ms, si vous la calculez, même au moment le plus chargé, il y aura un retard de 10 opérations de mise à jour, et le temps d'attente maximum est de 200 ms, alors ça va.
S'il y a de nombreuses opérations de mise à jour qui peuvent être retardées dans une file d'attente mémoire, vous devez alors ajouter des machines pour permettre aux instances de service déployées sur chaque machine de traiter moins de données que le retard de mises à jour dans chacune. la file d'attente mémoire sera Il y aura moins d'opérations.
En fait, sur la base de l'expérience des projets précédents, d'une manière générale, la fréquence d'écriture des données est très faible, donc en fait, normalement, l'arriéré des opérations de mise à jour dans la file d'attente devrait être très faible. Pour des projets comme celui-ci qui ciblent une concurrence de lecture élevée et une architecture de mise en cache de lecture, d'une manière générale, les demandes d'écriture sont très faibles, et il serait bien que le QPS par seconde puisse atteindre quelques centaines.
Un calcul approximatif est effectivement effectué
S'il y a 500 opérations d'écriture par seconde, et si divisé en 5 tranches de temps, il y aura 100 opérations d'écriture toutes les 200 ms, divisé en 20 Dans la file d'attente mémoire, chaque file d'attente mémoire peut avoir un retard de 5 opérations d'écriture. Après chaque test de performances d'opération d'écriture, il est généralement terminé en 20 ms environ, de sorte que la demande de lecture des données dans chaque file d'attente mémoire ne sera suspendue que pendant un certain temps au maximum et sera définitivement renvoyée dans un délai de 200 ms.
Après le simple calcul de tout à l'heure, nous savons que le QPS d'écriture pris en charge par une seule machine ne pose pas de problème par centaines. Si le QPS d'écriture est multiplié par 10, alors la machine sera étendue, et la machine sera étendue. la machine sera agrandie de 10 fois. Chaque machine compte 20 files d'attente.
2. La simultanéité des demandes de lecture est trop élevée
Un test de résistance doit être effectué ici pour garantir que lorsque la situation ci-dessus se produit, il existe un autre risque, c'est-à-dire un risque important. Un certain nombre de demandes de lecture se produiront soudainement. Le délai de plusieurs dizaines de millisecondes dépend du service et du nombre de machines nécessaires pour gérer le pic de la situation extrême.
Mais comme toutes les données ne sont pas mises à jour en même temps, et que le cache n'expirera pas en même temps, le cache d'un petit nombre de données peut être invalide à chaque fois, et alors les requêtes de lecture correspondant à ces données arrivent simultanément. La quantité ne devrait pas être particulièrement importante.
3. Routage des demandes pour le déploiement d'instances multiservices
Peut-être que ce service déploie plusieurs instances, il faut alors s'assurer que les demandes d'opérations de mise à jour des données et des opérations de mise à jour du cache sont transmises via le serveur Nginx. est acheminé vers la même instance de service.
Par exemple, toutes les requêtes de lecture et d'écriture pour un même produit sont acheminées vers la même machine. Vous pouvez effectuer votre propre routage de hachage entre les services en fonction d'un certain paramètre de requête, ou vous pouvez utiliser la fonction de routage de hachage de Nginx, etc.
4. Le problème de routage des produits chauds entraîne des requêtes asymétriques
Si les requêtes de lecture et d'écriture d'un certain produit sont particulièrement élevées et qu'elles sont toutes envoyées dans la même file d'attente de la même machine, il peut causer La pression sur une certaine machine est trop élevée. C'est-à-dire que parce que le cache ne sera vidé que lorsque les données du produit seront mises à jour, puis une simultanéité de lecture et d'écriture se produira, cela dépend donc en fait du système d'entreprise. Si la fréquence de mise à jour n'est pas trop élevée, l'impact de cela. Le problème n'est pas particulièrement important, mais il est vrai que la charge sur certaines machines peut être plus élevée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds



La clé primaire MySQL ne peut pas être vide car la clé principale est un attribut de clé qui identifie de manière unique chaque ligne dans la base de données. Si la clé primaire peut être vide, l'enregistrement ne peut pas être identifié de manière unique, ce qui entraînera une confusion des données. Lorsque vous utilisez des colonnes entières ou des UUIdes auto-incrémentales comme clés principales, vous devez considérer des facteurs tels que l'efficacité et l'occupation de l'espace et choisir une solution appropriée.

MySQL peut renvoyer les données JSON. La fonction JSON_Extract extrait les valeurs de champ. Pour les requêtes complexes, envisagez d'utiliser la clause pour filtrer les données JSON, mais faites attention à son impact sur les performances. Le support de MySQL pour JSON augmente constamment, et il est recommandé de faire attention aux dernières versions et fonctionnalités.

MySQL ne peut pas fonctionner directement sur Android, mais il peut être implémenté indirectement en utilisant les méthodes suivantes: à l'aide de la base de données légère SQLite, qui est construite sur le système Android, ne nécessite pas de serveur distinct et a une petite utilisation des ressources, qui est très adaptée aux applications de périphériques mobiles. Connectez-vous à distance au serveur MySQL et connectez-vous à la base de données MySQL sur le serveur distant via le réseau pour la lecture et l'écriture de données, mais il existe des inconvénients tels que des dépendances de réseau solides, des problèmes de sécurité et des coûts de serveur.

1. Utilisez l'index correct pour accélérer la récupération des données en réduisant la quantité de données numérisées SELECT * FROMMLOYEESEESHWHERELAST_NAME = 'SMITH'; Si vous recherchez plusieurs fois une colonne d'une table, créez un index pour cette colonne. If you or your app needs data from multiple columns according to the criteria, create a composite index 2. Avoid select * only those required columns, if you select all unwanted columns, this will only consume more server memory and cause the server to slow down at high load or frequency times For example, your table contains columns such as created_at and updated_at and timestamps, and then avoid selecting * because they do not require inefficient query se

MySQL peut gérer plusieurs connexions simultanées et utiliser le multi-threading / multi-processus pour attribuer des environnements d'exécution indépendants à chaque demande client pour s'assurer qu'ils ne sont pas dérangés. Cependant, le nombre de connexions simultanées est affectée par les ressources système, la configuration MySQL, les performances de requête, le moteur de stockage et l'environnement réseau. L'optimisation nécessite la prise en compte de nombreux facteurs tels que le niveau de code (rédaction de SQL efficace), le niveau de configuration (ajustement max_connections), niveau matériel (amélioration de la configuration du serveur).

MySQL a une version communautaire gratuite et une version d'entreprise payante. La version communautaire peut être utilisée et modifiée gratuitement, mais le support est limité et convient aux applications avec des exigences de stabilité faibles et des capacités techniques solides. L'Enterprise Edition fournit une prise en charge commerciale complète pour les applications qui nécessitent une base de données stable, fiable et haute performance et disposées à payer pour le soutien. Les facteurs pris en compte lors du choix d'une version comprennent la criticité des applications, la budgétisation et les compétences techniques. Il n'y a pas d'option parfaite, seulement l'option la plus appropriée, et vous devez choisir soigneusement en fonction de la situation spécifique.

Guide d'optimisation des performances de la base de données MySQL dans les applications à forte intensité de ressources, la base de données MySQL joue un rôle crucial et est responsable de la gestion des transactions massives. Cependant, à mesure que l'échelle de l'application se développe, les goulots d'étranglement des performances de la base de données deviennent souvent une contrainte. Cet article explorera une série de stratégies efficaces d'optimisation des performances MySQL pour garantir que votre application reste efficace et réactive dans des charges élevées. Nous combinerons des cas réels pour expliquer les technologies clés approfondies telles que l'indexation, l'optimisation des requêtes, la conception de la base de données et la mise en cache. 1. La conception de l'architecture de la base de données et l'architecture optimisée de la base de données sont la pierre angulaire de l'optimisation des performances MySQL. Voici quelques principes de base: sélectionner le bon type de données et sélectionner le plus petit type de données qui répond aux besoins peut non seulement économiser un espace de stockage, mais également améliorer la vitesse de traitement des données.

Les principales raisons pour lesquelles vous ne pouvez pas vous connecter à MySQL en tant que racines sont des problèmes d'autorisation, des erreurs de fichier de configuration, des problèmes de mot de passe incohérents, des problèmes de fichiers de socket ou une interception de pare-feu. La solution comprend: vérifiez si le paramètre Bind-Address dans le fichier de configuration est configuré correctement. Vérifiez si les autorisations de l'utilisateur racine ont été modifiées ou supprimées et réinitialisées. Vérifiez que le mot de passe est précis, y compris les cas et les caractères spéciaux. Vérifiez les paramètres et les chemins d'autorisation du fichier de socket. Vérifiez que le pare-feu bloque les connexions au serveur MySQL.
