Maison >base de données >Redis >Comment résoudre le problème de cache Redis

Comment résoudre le problème de cache Redis

PHPz
PHPzavant
2023-06-03 17:56:411196parcourir

LevelDB est là !

Il s'agit d'une bibliothèque de moteur de stockage NOSQL open source par Google, qui est un outil indispensable dans le domaine du stockage distribué moderne. Sur cette base, Facebook a développé une autre bibliothèque de moteur de stockage NOSQL, RocksDB, qui suit l'architecture technique avancée de LevelDB tout en résolvant certaines des lacunes de LevelDB. Vous pouvez comparer RocksDB à une bombe à hydrogène, qui est plus puissante que LevelDB. De nombreuses bases de données open source modernes utilisent RocksDB comme moteur de stockage sous-jacent, et TiDB en est l'un des exemples célèbres.

Mais pourquoi devrais-je parler de LevelDB au lieu de RocksDB ? La raison en est que l’architecture technique de LevelDB est plus simple, plus claire et plus facile à comprendre. Si nous comprenons d'abord parfaitement LevelDB, puis examinons RocksDB, il sera très facile de comprendre que RocksDB n'est qu'une série d'optimisations basées sur LevelDB. Lorsque nous résolvons le problème de RocksDB, le vaisseau spatial à propulsion nucléaire de TiDB nous accueille déjà pas très loin.

Quel est le problème avec le cache Redis ?

Lorsque nous utilisons Redis comme cache, il existe généralement toujours une base de données persistante qui enregistre l'intégralité des données froides et chaudes. La cohérence des données entre Redis et la base de données de la couche de persistance est contrôlée par l'application elle-même. Lorsqu'il n'y a aucune donnée dans le cache, l'application doit charger les données de la couche de persistance et les placer dans le cache. Lorsque des mises à jour de données ont lieu, le cache doit être invalidé.

<code class="hljs javascript">function getUser(String userId) User {<br>  User user = redis.get(userId);<br>  if user == null {<br>    user = db.get(userId);<br>    if user != null {<br>      redis.set(userId, user);<br>    }<br>  }<br>  return user;<br>}<br><br>function updateUser(String userId, User user) {<br>  db.update(userId, user);<br>  redis.expire(userId);<br>}<br></code>


Les amis qui ont une expérience en développement dans ce domaine savent qu'écrire un tel code est assez fastidieux. Tous les codes commerciaux impliquant la mise en cache doivent ajouter cette partie de logique.

À proprement parler, nous devons également examiner attentivement le problème de cohérence du cache. Par exemple, dans la méthode updateUser, la base de données effectue correctement la mise à jour, mais le redis mis en cache ne parvient pas à être invalidé en raison de la gigue du réseau et d'autres raisons, puis les données dans le cache deviennent des données expirées. Les lecteurs peuvent considérer que même si l’ordre de configuration du cache et de mise à jour du stockage persistant est inversé, d’autres problèmes peuvent encore survenir.

Les situations de concurrence élevée avec plusieurs processus peuvent également entraîner une incohérence du cache. Par exemple, si un processus appelle la méthode getUser() sur un certain identifiant utilisateur, car il n'est pas dans le cache, il doit être chargé à partir de la base de données. Les résultats viennent d'être chargés et nous sommes sur le point de configurer le cache. A ce moment, le code de la mémoire fullgc est mis en pause pendant un moment, un autre processus appelle la méthode updateUser pour mettre à jour la base de données et invalider le cache (en). en fait, il n'y a pas de cache dans les données du cache). Ensuite, le processus précédent termine enfin fullgc et commence à configurer le cache. À ce moment, les données expirées sont mises en cache.

Comment LevelDB est-il résolu ?

LevelDB combine le cache Redis et la couche de persistance en une seule, vous aidant à gérer simultanément la couche de cache et de persistance. Avec LevelDB, votre code peut être simplifié comme suit

<code class="hljs javascript">function getUser(String userId) User {<br>  return leveldb.get(userId);<br>}<br><br>function updateUser(String userId, User user) {<br>  leveldb.set(userId, user);<br>}<br></code>


et vous n'avez plus à vous soucier des problèmes de cohérence du cache. Les mises à jour des données dans LevelDB sont réussies ou infructueuses, et il n'y a pas d'état Schrödinger intermédiaire. Les utilisateurs n'ont pas besoin de prêter attention aux détails de la cohérence des données, car LevelDB intègre en interne le cache mémoire et les fichiers disque de la couche de persistance.

Qu'est-ce que LevelDB exactement ?

Nous avons mentionné précédemment qu'il s'agit d'un moteur de stockage non relationnel, différent du concept de Redis. Redis est une base de données complète, tandis que LevelDB n'est qu'un moteur. Si la base de données est comparée à une voiture de sport haut de gamme, le moteur de stockage est son moteur, c'est-à-dire son noyau et son cœur. Avec ce moteur, nous pouvons l'emballer avec une série d'accessoires et de décorations pour devenir une base de données. Mais ne sous-estimez pas les accessoires et les décorations. Il est très difficile d’atteindre le summum. L’empaquetage de LevelDB dans une base de données simple et facile à utiliser nécessite l’ajout de trop d’accessoires exquis. LevelDB et RocksDB existent depuis de nombreuses années, mais très peu peuvent créer une base de données complète au niveau de la production basée sur eux.

LevelDB peut être considérée comme une base de données clé-valeur en mémoire. Il fournit une API Get/Set de base grâce à laquelle nous pouvons lire et écrire des données dans notre code. Vous pouvez également le considérer comme un HashMap avancé de taille illimitée. Nous pouvons y insérer un nombre illimité de données clé/valeur tant que le disque peut les contenir.

Parce qu'elle ne peut être considérée que comme une base de données en mémoire, les données qui y sont stockées ne peuvent pas être partagées entre des processus ou des machines. Dans le domaine distribué, comment LevelDB peut-il montrer ses talents ?

Pour y parvenir, l'API réseau doit être intégrée au-dessus de la base de données en mémoire LevelDB. Lorsque plusieurs processus se trouvent sur des machines différentes et souhaitent accéder à la ressource, ils doivent tous y accéder de manière uniforme via l'interface API réseau. Cela forme une base de données simple. Appliquez le protocole Redis pour encapsuler la couche réseau et vous pouvez utiliser le client Redis pour lire et écrire la base de données.

Si nous voulons considérer la haute disponibilité de la base de données, nous pouvons la transformer en une base de données NOSQL distribuée avec une structure maître-esclave en ajoutant la fonction de réplication maître-esclave à la base de données autonome ci-dessus. L'ajout d'une couche de proxy de transfert (équilibreur de charge tel que LVS, F5, etc.) devant la base de données maître-esclave peut réaliser une commutation en temps réel de la base de données maître-esclave.

Si la capacité de données dont vous avez besoin est si grande que le disque dur d'une seule machine ne peut pas la contenir, un mécanisme de partage des données est nécessaire pour disperser l'intégralité des données de la base de données sur plusieurs machines. Chaque machine n'est responsable que d'une partie de la lecture et de l'écriture. les données. Il existe de nombreuses options pour le partage de données. Il peut être partagé via un proxy de transfert comme Codis, ou il peut être partagé à l'aide d'un mécanisme de transfert client comme Redis-Cluster. Il peut également être regroupé et géré à l'aide de l'algorithme de cohérence distribuée Raft. Le plus simple et le plus facile à comprendre est le partage de proxy direct de Codis.

Lorsque la quantité de données continue de croître et que de nouveaux nœuds sont nécessaires, les données des anciens nœuds doivent être partiellement migrées vers les nouveaux nœuds. Ce qui gère l'équilibre et la migration des données est un nouvel accessoire avancé : l'équilibreur de données.

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer