Parlons des transactions dans Redis : mode transaction, script Lua
青灯夜游
Libérer: 2023-04-10 19:29:36
avant
1561 Les gens l'ont consulté
Cet article vous donnera une compréhension approfondie des transactions Redis et comparera les deux modes de transactions Redis (mode transaction et script Lua). J'espère qu'il sera utile à tout le monde !
Pour être précis, les transactions Redis incluent deux modes : Mode transaction et Script Lua.
Commençons par la conclusion :
Le modèle de transaction de Redis présente les caractéristiques suivantes :
garantit l'isolement ;
ne peut pas garantir la durabilité ;
a un certain degré d'atomicité, mais ne prend pas en charge le rollback ; Il y a des différences de concepts.On suppose que les transactions Redis peuvent garantir la cohérence sous la sémantique selon laquelle le cœur de la cohérence est constitué de contraintes.
Mais le script Lua a des scénarios plus pratiques. C'est une autre forme de transaction. Il a un certain degré d'atomicité, mais lorsque le script signale une erreur, la transaction ne sera pas annulée. Les scripts Lua peuvent assurer l'isolement et peuvent parfaitement prendre en charge
Les étapes suivantes dépendent des résultats des étapes précédentes
Le mode script Lua est presque partout, comme les verrous distribués, les files d'attente retardées, la saisie d'enveloppes rouges et d'autres scénarios.
1 Principe de transaction
Les transactions Redis incluent les commandes suivantes :
Numéro de série
Commande et description
1
MULTI marque le début d'un bloc de transaction.
2
EXEC exécute toutes les commandes dans le bloc de transaction.
3
DISCARD annule la transaction et abandonne l'exécution de toutes les commandes au sein du bloc de transaction.
4
WATCH key [key ...] Surveille une (ou plusieurs) clés. Si cette (ou ces) clés sont modifiées par d'autres commandes avant l'exécution de la transaction, la transaction sera interrompue.
5
UNWATCH annule la surveillance de toutes les touches par la commande WATCH.
La transaction se compose de trois étapes :
La transaction est ouverte, en utilisant MULTI, cette commande marque le client exécutant la commande passant de l'état non transactionnel à l'état transactionnel
La commande est mise en file d'attente, une fois que MULTI a ouvert la transaction, la commande du client Il ; ne sera pas exécuté immédiatement, mais sera placé dans une file d'attente de transactions ;
Exécutez la transaction ou supprimez-la. Si une commande EXEC est reçue, la commande dans la file d'attente des transactions sera exécutée. Si elle est DISCARD, la transaction sera rejetée.
Ce qui suit montre un exemple de transaction.
1
redis> MULTI
2
OK
3
redis> SET msg "hello world"
4
QUEUED
5
redis> GET msg
6
QUEUED
7
redis> EXEC
8
1) OK
9
1) hello world
Copier après la connexion
Vous avez une question ici ? La clé Redis peut-elle être modifiée lors du démarrage d'une transaction ?
Avant que la transaction n'exécute la commande EXEC, la clé Redis peut toujours être modifiée.
Avant de démarrer la transaction, nous pouvons utiliser la commande watch pour surveiller la clé Redis. Avant que la transaction ne soit exécutée, nous modifions la valeur de la clé. Si la transaction échoue, nil est renvoyé.
Grâce à l'exemple ci-dessus, la commande watch peut obtenir un effet similaire au verrouillage optimiste.
2 ACIDE de transaction
2.1 Atomicité
Atomicité signifie : toutes les opérations d'une transaction sont soit entièrement terminées, soit non terminées, et ne se termineront pas par un lien intermédiaire. Si une erreur se produit lors de l'exécution de la transaction, elle sera restaurée à l'état avant le début de la transaction, comme si la transaction n'avait jamais été exécutée.
Premier exemple :
Avant d'exécuter la commande EXEC, la commande d'opération envoyée par le client est erronée, comme une erreur de syntaxe ou une commande inexistante.
1
redis> MULTI
2
OK
3
redis> SET msg "other msg"
4
QUEUED
5
redis> wrongcommand ### 故意写错误的命令
6
(error) ERR unknown command 'wrongcommand'
7
redis> EXEC
8
(error) EXECABORT Transaction discarded because of previous errors.
9
redis> GET msg
10
"hello world"
Copier après la connexion
Dans cet exemple, nous avons utilisé une commande qui n'existe pas, provoquant l'échec de la mise en file d'attente et l'échec de l'exécution de la transaction entière.
Deuxième exemple :
Lorsque l'opération de transaction est mise en file d'attente, les types de données de la commande et de l'opération ne correspondent pas. La mise en file d'attente est normale, mais l'exécution de la commande EXEC est anormale.
1
redis> MULTI
2
OK
3
redis> SET msg "other msg"
4
QUEUED
5
redis> SET mystring "I am a string"
6
QUEUED
7
redis> HMSET mystring name "test"
8
QUEUED
9
redis> SET msg "after"
10
QUEUED
11
redis> EXEC
12
1) OK
13
2) OK
14
3) (error) WRONGTYPE Operation against a key holding the wrong kind of value
15
4) OK
16
redis> GET msg
17
"after"
Copier après la connexion
Dans cet exemple, si une erreur se produit lorsque Redis exécute la commande EXEC, Redis ne mettra pas fin à l'exécution des autres commandes et la transaction ne sera pas annulée car une certaine commande ne parvient pas à s'exécuter.
Pour résumer, ma compréhension de l'atomicité des transactions Redis est la suivante :
Si une erreur est signalée lorsque la commande est mise en file d'attente, l'exécution de la transaction sera abandonnée pour garantir l'atomicité ; mis en file d'attente, et une erreur sera signalée après l'exécution de la commande EXEC, ce qui ne garantit pas l'atomicité
C'est-à-dire : Les transactions Redis n'ont qu'une certaine atomicité
sous certaines conditions.
2.2 Isolation L'isolation de la base de données fait référence à la capacité de la base de données à permettre à plusieurs transactions simultanées de lire, d'écrire et de modifier ses données en même temps. L'isolation peut empêcher l'exécution simultanée de plusieurs transactions en raison de croisements. exécution conduisant à une incohérence des données.
L'isolement des transactions est divisé en différents niveaux, qui sont :
lecture non validée
lecture validée
lecture répétable
sérialisable
Tout d'abord, il faut être clair : Redis n'a pas le concept de transaction niveau d'isolement. Nous discutons ici de l'isolement de Redis :
Dans un scénario simultané, si les transactions peuvent éviter d'interférer les unes avec les autres
. Nous pouvons diviser l'exécution de la transaction en deux étapes :
avant l'exécution de la commande EXEC
et commande EXEC après l'exécution, et en discuter séparément.
Avant d'exécuter la commande EXECDans la section sur les principes de transaction, nous avons constaté que la clé Redis peut toujours être modifiée avant l'exécution de la transaction. À ce stade, vous pouvez utiliser le mécanisme WATCH
pour obtenir l'effet de verrouillage optimiste.
Après l'exécution de la commande EXECÉtant donné que Redis est une commande d'exécution à thread unique, une fois la commande EXEC exécutée, Redis garantira que toutes les commandes de la file d'attente de commandes sont exécutées. Cela garantit l’isolement des transactions.
2.3 DurabilitéLa persistance de la base de données signifie : une fois la transaction terminée, la modification des données est permanente et ne sera pas perdue même en cas de panne du système.
La persistance des données Redis dépend du mode de configuration de persistance de Redis.
Sans RDB ou AOF configuré, la durabilité de la transaction ne peut pas être garantie
En utilisant le mode RDB, après l'exécution d'une transaction et avant l'exécution du prochain instantané RDB, si un crash d'instance se produit, la durabilité de la transaction ; Il n'y a également aucune garantie ;
utilise le mode AOF ; les trois options de configuration du mode AOF, no et everysec, entraîneront une perte de données. peut toujours garantir la durabilité des transactions, mais comme les performances sont trop médiocres, il n'est généralement pas recommandé de l'utiliser dans des environnements de production.
En résumé, la pérennité des transactions redis ne peut être garantie
.
2.4 CohérenceLe concept de cohérence a toujours prêté à confusion. Dans les informations que j'ai recherchées, il existe deux définitions différentes.
Wikipedia
Regardons d'abord la définition de la cohérence sur Wikipédia :
La cohérence garantit qu'une transaction ne peut que faire passer la base de données d'un état valide à un autre, en maintenant les invariants de la base de données : toutes les données écrites dans la base de données doivent être valides. selon toutes les règles définies, y compris les contraintes, les cascades, les déclencheurs et toute combinaison de celles-ci. Cela empêche la corruption de la base de données par une transaction illégale, mais ne garantit pas qu'une transaction est correcte.
Dans ce texte, le cœur de la cohérence est "
contraintes
", "toute donnée écrite dans la base de données doit être valide selon toutes les règles définies". Comment comprendre les contraintes ? Voici une citation de la question Zhihu
Comment comprendre la cohérence interne et la cohérence externe de la base de données
, et un passage auquel Han Fusheng, un expert R&D OceanBase chez Ant Financial a répondu :
Les "contraintes" sont indiquées par l'utilisateur de la base de données à la base de données, et l'utilisateur exige que les données soient sûres de respecter telle ou telle contrainte. Lorsque les données sont modifiées, la base de données vérifiera si les données répondent toujours aux contraintes. Si les contraintes ne sont plus satisfaites, l'opération de modification n'aura pas lieu.
Les deux types de contraintes les plus courants dans les bases de données relationnelles sont les « contraintes uniques » et les « contraintes d'intégrité ». La clé primaire et la clé unique définies dans la table garantissent que les éléments de données spécifiés ne seront jamais répétés. L'intégrité garantit également la cohérence du même attribut dans les différentes tables.
"Cohérence dans ACID" est si facile à utiliser qu'il a été fondu dans le sang de la plupart des utilisateurs. Les utilisateurs ajouteront consciemment les contraintes requises lors de la conception des tables, et la base de données les implémentera strictement.
Donc
la cohérence des transactions est liée à des contraintes prédéfinies. Assurer des contraintes, c'est assurer la cohérence
. Regardons de plus près cette phrase :
Cela empêche la corruption de la base de données par une transaction illégale, mais ne garantit pas qu'une transaction est correcte
. Vous êtes peut-être encore un peu confus après avoir écrit ceci. Prenons un cas classique de
transfert
. Nous commençons une transaction. Les soldes initiaux sur les comptes de Zhang San et Li Si sont tous deux de 1 000 yuans, et il n'y a aucune contrainte sur le champ du solde. Zhang San a transféré 1 200 yuans à Li Si. Le solde de Zhang San est mis à jour à -200 et celui de Li Si est mis à jour à 2200.
Au niveau de l'application, cette transaction est évidemment illégale, car dans des scénarios réels, le solde utilisateur ne peut pas être inférieur à 0, mais elle suit complètement les contraintes de la base de données, donc au niveau de la base de données, cette transaction garantit toujours la cohérence.
La cohérence des transactions de Redis signifie que les transactions Redis sont conformes aux contraintes de la base de données lors de l'exécution et ne contiennent pas de données d'erreur illégales ou invalides.
Nous discutons respectivement de trois scénarios d'exception :
Avant d'exécuter la commande EXEC, la commande d'opération envoyée par le client est erronée, la transaction est terminée et les données restent cohérentes ;
Après l'exécution de la commande EXEC, les données de commande et d'opération Si le type ne correspond pas, la mauvaise commande signalera une erreur, mais la transaction ne sera pas terminée en raison d'une mauvaise commande, mais continuera à s'exécuter. La bonne commande est exécutée normalement, et la mauvaise commande signale une erreur. De ce point de vue, les données peuvent également maintenir la cohérence
Lors de l'exécution de la transaction, le service Redis tombe en panne. Ici, vous devez considérer le mode de persistance de la configuration du service.
Mode mémoire sans persistance : Après le redémarrage du service, la base de données ne conserve pas les données, donc les données restent cohérentes ;
Mode RDB/AOF : Après le redémarrage du service, Redis restaure les données via les fichiers RDB/AOF, et la base de données ; restaurera à un état cohérent.
Pour résumer, Sous la sémantique selon laquelle le cœur de la cohérence est la contrainte, les transactions Redis peuvent garantir la cohérence
.
"Concevoir des applications à forte intensité de données"Ce livre est un livre magique pour démarrer avec les systèmes distribués. Il y a une explication sur ACID dans le chapitre sur les transactions :
L'atomicité, l'isolation et la durabilité sont des propriétés de la base de données, tandis que la cohérence (au sens ACID) est une propriété de l'application. Les propriétés d'atomicité et d'isolation de la base de données afin d'obtenir une cohérence, mais cela ne dépend pas uniquement de la base de données. Ainsi, la lettre C n'appartient pas vraiment à ACID.
L'atomicité, l'isolation et la durabilité sont des propriétés de la base de données, alors que la cohérence ( au sens ACID) est une propriété de l'application. Les applications peuvent s'appuyer sur les propriétés d'atomicité et d'isolation de la base de données pour assurer la cohérence, mais cela ne dépend pas uniquement de la base de données. La lettre C n’appartient donc pas à ACID.
Souvent, la cohérence avec laquelle nous avons lutté fait en fait référence à
la cohérence en accord avec le monde réel
. La cohérence dans le monde réel est le but ultime des affaires. Afin d'atteindre une cohérence dans le monde réel, les points suivants doivent être respectés :
Garantir l'atomicité, la durabilité et l'isolement. Si ces caractéristiques ne peuvent pas être garanties, alors la cohérence de la transaction ne peut pas être garantie ;
Les contraintes de la base de données elle-même, telles que la longueur des chaînes, ne peuvent pas dépasser les limites de colonnes ou les contraintes uniques ; Le niveau doit également être protégé.
2.5 Fonctionnalités de transactionNous appelons généralement Redis une base de données en mémoire Différente des bases de données relationnelles traditionnelles, afin de fournir des performances plus élevées et une vitesse d'écriture plus rapide, certaines choses ont été faites au niveau de la conception et de la mise en œuvre. Balanced ne prend pas entièrement en charge l’ACID transactionnel.
Les transactions Redis ont les caractéristiques suivantes :
garantit l'isolement ;
ne peut pas garantir la durabilité ;
a un certain degré d'atomicité, mais ne prend pas en charge le rollback ; La cohérence est que sous la sémantique des contraintes, les transactions Redis peuvent assurer la cohérence.
D'un point de vue technique, en supposant que chaque étape d'une opération de transaction doit s'appuyer sur le résultat renvoyé par l'étape précédente, le verrouillage optimiste doit être implémenté via watch.
3 Script Lua
3.1 Introduction
Lua est écrit en standard C. Le code est simple et beau, et peut être compilé et exécuté sur presque tous les systèmes d'exploitation et plates-formes. Les scripts Lua peuvent être facilement appelés par du code C/C++, et peuvent également appeler des fonctions C/C++ à leur tour, ce qui rend Lua largement utilisé dans les applications.
Les scripts Lua ont brillé dans le domaine du jeu. Les célèbres "Westward Journey II" et "World of Warcraft" utilisent tous deux largement les scripts Lua. Les scripts Lua peuvent être vus dans les passerelles API avec lesquelles les ingénieurs backend Java sont entrés en contact, telles que
Openresty
et
Kong
. À partir de la version 2.6.0 de Redis, l'interpréteur Lua intégré de Redis peut exécuter des scripts Lua dans Redis. Avantages de l'utilisation des scripts Lua :
Réduisez la surcharge du réseau. Envoyez plusieurs requêtes à la fois sous la forme d'un script pour réduire la latence du réseau. Opérations atomiques. Redis exécutera l'intégralité du script dans son ensemble et aucune autre commande ne sera insérée au milieu.
Réutiliser. Le script envoyé par le client sera stocké de manière permanente dans Redis, et d'autres clients pourront réutiliser ce script sans utiliser de code pour compléter la même logique.
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn