La position actuelle:Accueil du site>Comment renouveler automatiquement les serrures distribuées redis (solution classique)
Comment renouveler automatiquement les serrures distribuées redis (solution classique)
2022-07-23 00:14:36【Les dragons montent des officiels.】
Table des matières
Redis Réaliser des serrures distribuées
1.1.Renouvellement automatique
2.1.Comment les chiens de garde renouvellent automatiquement
2.1.1Principe de renouvellement
Redis Réaliser des serrures distribuées
Spécifiez un key Comme marque de verrouillage,Dépôt Redis Moyenne,Spécifiez un Un identifiant utilisateur unique comme value.
Quand key La valeur ne peut être définie que lorsqu'elle n'existe pas,Assurez - vous qu'un seul processus client obtient le verrouillage en même temps,Satisfaire aux caractéristiques d'exclusion mutuelle.
Fixer un délai d'expiration,Empêcher que cela ne puisse être supprimé en raison d'une exception au système key,Satisfait aux caractéristiques anti - blocage.
Vous devez effacer ceci après avoir traité l'affaire key Pour libérer la serrure,Effacer key Vérification requise value Valeur,Besoin de satisfaire que seule la personne qui a ajouté la serrure peut libérer la serrure .
1、Questions
Si cette serrure expire30Secondes,Mais les affaires ont dépassé30Secondes,Par exemple,40Secondes,Quand les affaires tournent30En quelques secondes,La serrure est expirée.,Les autres clients ont cette serrure,Comment faire?
On peut fixer un délai raisonnable,Permettre aux entreprises de compléter la logique d'entreprise dans ce délai,Mais...LockTimeLe réglage de n'était pas facile.
LockTimeRéglage trop petit,La probabilité que la serrure s'éteigne automatiquement augmente,La probabilité de défaillance anormale de la serrure augmente également;
LockTimeRéglage trop grand,En cas d'exception au service qui ne libère pas correctement la serrure,Plus il faudra de temps pour que cette serrure anormale se produise.
Nous ne pouvons configurer que par expérience,Une valeur acceptable,En gros, c'est le temps moyen que ce service a pris dans l'histoire, un peu plusbuff.Dans l'ensemble,Il n'est pas facile de fixer un délai d'expiration raisonnable
On peut aussi ne pas fixer de délai d'expiration,Déverrouiller une fois l'opération terminée,Mais si le client a une fin anormale ou un temps d'arrêt,Alors cette serrure ne se déverrouillera pas,C'est devenu une impasse;
1.1.Renouvellement automatique
On peut d'abord régler la serrureLockTime,Puis lancez un Thread de démon,Laissez le thread du démon,Pour réinitialiser cette serrureLockTime.
Ça a l'air simple,Mais ce n'est pas facile à réaliser
Comme pour le déverrouillage,Nous devons d'abord déterminer s'il y a un changement dans le client hold Lock.Sinon, celui qui tient la serrure,Les fils du démon vont réinitialiser la serrureLockTime.
Le thread du démon doit réinitialiser la serrure dans un délai raisonnableLockTime,Sinon, les ressources seront gaspillées.On ne peut pas continuer sans bouger.
Si le thread qui détient la serrure a fini de traiter l'affaire,Alors le thread du démon devrait aussi être détruit.L'opération n'est pas terminée,Le gardien est toujours là,Gaspiller des ressources.
2.Chien de garde
RedissonC'est ce mécanisme qui permet le renouvellement automatique:
Redissson tryLock
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long time = unit.toMillis(waitTime);
long current = System.currentTimeMillis();
long threadId = Thread.currentThread().getId();
// 1.Essayer d'obtenir une serrure
Long ttl = tryAcquire(leaseTime, unit, threadId);
// lock acquired
if (ttl == null) {
return true;
}
// Le temps nécessaire pour demander un verrouillage est égal ou supérieur au temps d'attente maximal,La demande de verrouillage a échoué.
time -= System.currentTimeMillis() - current;
if (time <= 0) {
acquireFailed(threadId);
return false;
}
current = System.currentTimeMillis();
/**
* 2.Événement de libération des serrures d'abonnement,Et à travers await Méthode bloquée en attendant la libération de la serrure,Résoudre efficacement le problème des demandes de verrouillage invalides qui gaspillent des ressources:
* Basé sur la quantité d'informations,Lorsque la serrure est occupée par d'autres ressources,Le thread actuel passe par Redis De channel Événement de libération de la serrure d'abonnement,Une fois le verrouillage libéré, un message est envoyé pour informer les Threads en attente de la concurrence.
*
* Quand this.await Retour false,Indique que le temps d'attente a dépassé le temps d'attente maximal pour obtenir la serrure,Échec de la désabonnement et du retour pour obtenir le verrouillage.
* Quand this.await Retour true,Entrez le cycle pour essayer d'obtenir la serrure.
*/
RFuture<RedissonLockEntry> subscribeFuture = subscribe(threadId);
// await L'intérieur de la méthode est CountDownLatch Pour obtenir un blocage,Accès subscribe Résultats de l'exécution asynchrone(Appliqué Netty De Future)
if (!subscribeFuture.await(time, TimeUnit.MILLISECONDS)) {
if (!subscribeFuture.cancel(false)) {
subscribeFuture.onComplete((res, e) -> {
if (e == null) {
unsubscribe(subscribeFuture, threadId);
}
});
}
acquireFailed(threadId);
return false;
}
try {
// Calculer le temps total nécessaire pour obtenir la serrure,Si le temps d'attente maximal est supérieur ou égal à,Impossible d'obtenir la serrure.
time -= System.currentTimeMillis() - current;
if (time <= 0) {
acquireFailed(threadId);
return false;
}
/**
* 3.Après avoir reçu le signal de déverrouillage,Dans le délai maximum d'attente,Essayez d'obtenir la serrure encore et encore
* Obtenir la serrure avec succès,Je reviens tout de suite true,
* Si la serrure n'a pas été obtenue dans le délai d'attente maximal,L'acquisition de la serrure est considérée comme un échec,Retour false Fin du cycle
*/
while (true) {
long currentTime = System.currentTimeMillis();
// Essayez encore d'obtenir la serrure
ttl = tryAcquire(leaseTime, unit, threadId);
// lock acquired
if (ttl == null) {
return true;
}
// Si le temps d'attente maximal est dépassé, il retourne false Fin du cycle,Impossible d'obtenir la serrure
time -= System.currentTimeMillis() - currentTime;
if (time <= 0) {
acquireFailed(threadId);
return false;
}
/**
* 6.Blocage de la serrure d'attente(Signal de passage(Serrure partagée)Blocage,Attendez le message de déverrouillage):
*/
currentTime = System.currentTimeMillis();
if (ttl >= 0 && ttl < time) {
//Si le temps restant(ttl)Moins dewait time ,Juste là. ttl Dans le temps,DeEntryLe sémaphore de(À moins qu'il ne soit interrompu ou qu'il n'y ait pas de licence disponible).
getEntry(threadId).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);
} else {
//Alors c'est justewait time L'attente dans le temps peut passer par le sémaphore
getEntry(threadId).getLatch().tryAcquire(time, TimeUnit.MILLISECONDS);
}
// Mettre à jour le temps d'attente restant(Temps d'attente maximum-Temps de blocage écoulé)
time -= System.currentTimeMillis() - currentTime;
if (time <= 0) {
acquireFailed(threadId);
return false;
}
}
} finally {
// 7.Avec ou sans serrure,Pour désabonner les messages de déverrouillage
unsubscribe(subscribeFuture, threadId);
}
return get(tryLockAsync(waitTime, leaseTime, unit));
}Essayer d'obtenir une serrure,Retour null Cela signifie que le verrouillage est réussi,Renvoie une valeur numérique,La serrure existe déjà,ttl Pour la durée de vie restante de la serrure.
Si le client 2 Le processus n'a pas réussi à obtenir le verrouillage,Alors, utilisez le client 2 Les fils de id(En fait, c'est essentiellement le processus id)Adoption Redis De channel Événements pour la libération des serrures d'abonnement.Si la notification de l'événement de libération de la serrure n'est pas attendue pendant l'attente,Impossible d'obtenir la serrure lorsque le temps d'attente maximal est dépassé,Retour false,C'est la 39 Code de ligne.Si vous attendez la notification de l'événement de libération de la serrure,Commence un cycle de retry constant pour obtenir la serrure.
Essayez d'obtenir la serrure à chaque fois dans le cycle,Et obtenir la durée de vie restante des serrures existantes.Si vous avez la serrure en retry,Retour direct.Si la serrure est toujours occupée,Alors attendez le message pour libérer la serrure,La réalisation concrète utilise des sémaphores Semaphore Pour bloquer les fils,Lorsque la serrure est libérée et qu'un message de libération de la serrure est affiché,Sémaphore release() La méthode est appelée,Un thread dans la file d'attente bloquée par le sémaphore peut maintenant continuer à essayer d'obtenir le verrouillage.
Lorsque la serrure est occupée,Le processus d'attente pour obtenir la serrure ne passe pas par un while(true) Boucle morte pour obtenir la serrure,Mais en utilisant Redis Mécanisme d'abonnement à la publication pour,Adoption await Méthode pour bloquer le processus en attente de verrouillage,Résoudre efficacement le problème des demandes de verrouillage invalides qui gaspillent des ressources.
2.1.Comment les chiens de garde renouvellent automatiquement
RedissonMécanisme de chien de garde, Tant que le client est verrouillé avec succès,Et ça déclenche un Watch Dog.
leaseTime Ça doit l'être. -1 Ça s'ouvrira Watch Dog Mécanismes,Si nécessaire Watch Dog Le mécanisme doit utiliser le temps de verrouillage par défaut de 30s.
Si vous Personnalisez votre temps,Au - delà de ce temps,La serrure se libère,Pas de renouvellement automatique.
2.1.1Principe de renouvellement
Le principe du renouvellement est en fait utiliséluaScript,Réinitialiser le temps de verrouillage à30s.
private void scheduleExpirationRenewal(long threadId) {
ExpirationEntry entry = new ExpirationEntry();
ExpirationEntry oldEntry = EXPIRATION_RENEWAL_MAP.putIfAbsent(getEntryName(), entry);
if (oldEntry != null) {
oldEntry.addThreadId(threadId);
} else {
entry.addThreadId(threadId);
renewExpiration();
}
}
protected RFuture<Boolean> renewExpirationAsync(long threadId) {
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return 1; " +
"end; " +
"return 0;",
Collections.<Object>singletonList(getName()),
internalLockLeaseTime, getLockName(threadId));
}Watch Dog Le mécanisme est en fait un fil de tâche de synchronisation de fond,Après avoir obtenu la serrure avec succès,Placez le fil qui tient la serrure dans un RedissonLock.EXPIRATION_RENEWAL_MAPÀ l'intérieur,Et puis à chaque fois 10 Secondes (internalLockLeaseTime / 3) Vérifiez,Si le client Toujours avec la serrure key(Déterminer si le client détient toujours key,En fait, c'est la traversée. EXPIRATION_RENEWAL_MAP Le fil intérieur id Et puis selon le fil id Vas - y. Redis Central check,S'il existe, il sera prolongé key Le temps),Alors ça va continuer à allonger la serrure key La durée de vie de.
Si le service s'arrête,Watch Dog Il n'y a plus de fils de mécanisme,Il n'y aura pas de prolongation pour le moment key Date d'expiration,On y est. 30s Il expirera automatiquement après,D'autres fils peuvent obtenir la serrure.
Mentions de copyright
Auteur de cet article [Les dragons montent des officiels.],Réimpression s’il vous plaît apporter le lien vers l’original, merci
https://fra.chowdera.com/2022/204/202207221332102037.html
Recommandé par sidebar
- ACL - ijcai - Sigir top Conference Paper presentation Conference (ais 2022) Note 2: Analysis and interpretability
- Félicitations pour la tenue réussie du Forum sur la gestion de l'innovation de produits « innovation et autonomisation » le 16 juillet
- Leetcode - zj - future04: distribution des marchandises en magasin
- Idea décompile toute la source du paquet jar
- Cohérence finale transactions distribuées STC
- Développement d'ardunio - processus de fonctionnement des pompes
- Conception d'un système de consommation de supermarchés sans pilote basé sur stm32
- Classification de l'index MySQL et exemples d'utilisation
- Tas (file d'attente prioritaire)
- Utilisation et cas de regexp pour les déclarations MySQL
Devinez que vous aimez
【 série mysql】 "résoudre une fois pour toutes le problème de l'erreur" insérer des données chinoises "dans MySQL
2022 - 07 - 18 sous - Requête - optimisation du traitement de l'optimiseur de requête join pour le scénario exists
Notes de classe de la Silicon Valley (Partie 2)
Pytorch Deep Learning Practice - 1 - Overview
MySQL Exercise one database Knowledge
Succès de la construction du cluster expérimental tdengine
Enregistrer un résumé de la mesure de pression jmeter
Ssti Summary and ciscn 2019 South East China] double secret
Les bases de l'IOT - NB
Technologie des commutateurs et des routeurs: ACL standard, ACL étendu et ACL nommé
Recommandé au hasard
- ECCV 2022 | correction des dommages importants au rendement de la cible causés par le fpn: Vous devriez regarder tous les objets
- Chaque jour - jour 41 - 125. Vérifier la chaîne de palindromes
- [traduction de l'article] Aperçu du radiographe apprentissage par la surveillance croisée entre les images
- Codeforce D2. RGB substring (Hard version) Sliding Window
- Cause du tampon / cache du serveur et libération du tampon / cache
- NFS Shared Storage Service
- Ajout, suppression et modification de MySQL (niveau avancé)
- Pointeur de fonction C et fonction de rappel
- Qt Notes - nombre de lignes traînées et de mouvements pour le Widget qtablewidget
- Inscription des femmes
- Le mot de passe MySQL est correct, mais une erreur de démarrage n'a pas été signalée pour créer des connexions initiales de pool. Accès refusé pour l'utilisateur 'root' @ 'localhost
- 【 sdio】 résumé de l'analyse du Protocole sd2.0 (Ⅲ) - - Introduction aux commandes pertinentes de la carte SD
- App mobile End test [6] application (APK) package Management and Activity
- Qt | boîtes de dialogue modales et non modales qdialog
- Interrogation aléatoire de n données dans diverses bases de données
- Idea construit le projet jfinal + génération automatique de code + test de fonctionnement de la base de données (trois méthodes)
- Flutter premier programme Hello world!
- Constructeurs et destructeurs de classes dérivées
- Conception du modèle de données de la base de données newsql
- Résumé de fin d'année 2017
- Comment le détournement de DNS peut - il être parfaitement réparé? Comment résoudre le problème du détournement de DNS
- Flask Cross - Domain
- Mise en œuvre de la pile de chaînes (langage c)
- Lire attentivement le document DETR et analyser la structure du modèle
- [FPGA]: IP Core - - DDR3
- L'applet Wechat ne peut pas lire la propriété 'setdata' de NULL Error
- Buctf passing Diary - - [Netting Cup 2020 Qinglong Group] areuserialz
- Notes d'apprentissage du système intégré
- Cartesi mars 2022 Review
- Double pointeur quotidien leetcode - 7
- Ji Yuan Community ai Weekly # 90: Ma Yi pense que l'intelligence ne peut pas dépendre d'une grande puissance de calcul; Hugging face blog pour découvrir les détails de la formation bloom; Annonce du prix ICML pour la meilleure thèse
- Typescript
- Outils open source Introduction aux outils SAP ui5
- Guide du tutoriel Lark
- Sécurité du réseau - pénétration à l'aide d'une vulnérabilité de sécurité d'accès physique Evil Maid
- Sécurité du réseau - pénétration et renforcement à l'aide d'une vulnérabilité locale Ubuntu
- Rédaction de la classe d'outils jwt
- Boom 3D Serial Number Licensing superbes Sound Enhancement and player Tools
- Day1 Running SUMM of 1D Array / find pivot index / queue with two Stacks
- Introduction de l'API commune de programmation de socket et mise en œuvre de socket, select, Poll et epoll