当前位置:网站首页>Redis Distributed Lock
Redis Distributed Lock
2022-07-01 16:46:00 【Bugmaker Shen】
Catalogue des articles
Un.、Concept de serrure distribuée
Au fur et à mesure que l'entreprise évolue,Une fois que le système original déployé sur une seule machine a été transformé en un système de Clusters de distribution de composants,En raison du Multithreading du système distribué、Processus multiples et distribués sur différentes machines,Cela invalidera la politique de verrouillage du contrôle de la concurrence dans le cas d'un déploiement autonome original,Simple Java API La capacité de verrouillage distribué n'est pas disponible.Pour résoudre ce problème, il faut une approche transversale JVM Pour contrôler l'accès aux ressources partagées,C'est le problème avec les serrures distribuées!
C'est un peu vulgaire,Après avoir verrouillé le cluster,Quelle que soit la machine actuellement utilisée,Toutes les machines reconnaîtront et attendront,Aucune autre opération ne peut être effectuée tant que la serrure n'est pas relâchée,C'est la serrure distribuée,Valable pour tous les Clusters
Mise en œuvre de la serrure distribuée Mainstream:
- Verrouillage distribué basé sur la base de données
- Basé sur le cache(Redis Attendez.)
- Basé sur Zookeeper
Chaque solution de verrouillage distribuée a ses avantages et ses inconvénients,Parmi euxredisPerformance maximalezookeeperFiabilité maximale
2.、UtilisersetnxRéaliser la serrure
set stu:1:info “OK” nx px 10000
EX second :Définir l'expiration de la clé à second Secondes,,SET key value EX second L'effet est équivalent à SETEX key second value
PX millisecond :Définir l'expiration de la clé à millisecond MS,SET key value PX millisecond L'effet est équivalent à PSETEX key millisecond value
NX :Seulement si la clé n'existe pas,Pour définir la clé,SET key value NX L'effet est équivalent à SETNX key value
XX :Seulement si la clé existe déjà,Pour définir la clé
- Plusieurs clients obtiennent des serrures en même temps(setnx)
- Obtenir le succès,Exécuter la logique opérationnelle(De db Obtenir des données,Mise en cache),Exécuter la serrure de libération complète(del)
- Le client qui n'a pas réussi à obtenir attend de réessayer
AvecsetnxEtdel Ajouter et libérer des serrures
En général, Nous devons fixer un délai d'expiration pour les serrures afin qu'elles ne soient pas utilisées à long terme
Il y a un problème.: Le verrouillage et le réglage du délai d'expiration sont deux opérations , Au lieu de fonctionner simultanément , Si une condition anormale survient après le verrouillage , Impossible de définir le délai d'expiration .On peut.Régler le délai d'expiration pendant le verrouillage
Trois、Écrire un code pour tester les serrures distribuées
1. UtiliserJavaCode Test Distributed Lock
Tout d'abord,redisParamètres intermédiairesnumLa valeur de0,CompilationJavaCode à tester
Le code ci - dessous fait : Obtenir la serrure num++,Et relâchez la serrure; Si vous n'obtenez pas 0.1Récupérez dans quelques secondes
Redémarrer,Grappes de services, Réussir le test de résistance de la passerelle :ab -n 5000 -c 100 http://192.168.140.1:8080/test/testLock
Voir redis Moyenne num Valeur de
Questions: setnx J'ai juste eu la serrure,Exception à la logique opérationnelle,La serrure ne se libère pas
Résolution: Définir le délai d'expiration,Verrouillage automatique
2. Réglage optimisé du temps d'expiration de la serrure
Il y a deux façons de définir le temps d'expiration:
- Pensez d'abord à passer expire Définir le délai d'expiration(Manque d'atomicité:Si dans setnx Et expire De Anomalie interstitielle ,La serrure ne se libère pas non plus.)
- In set Indique également le délai d'expiration (Recommandations)
Définir le temps d'expiration dans le Code :
Questions: Les serrures d'autres serveurs peuvent être libérées
Si le temps d'exécution de la logique d'entreprise est 7s,Le processus d'exécution est le suivant::
- index1 La logique d'entreprise n'est pas terminée,3 La serrure est libérée automatiquement après quelques secondes
- index2 Obtenir la serrure,Exécuter la logique opérationnelle,3 La serrure est libérée automatiquement après quelques secondes
- index3 Obtenir la serrure,Exécuter la logique opérationnelle
- index1 Exécution de la logique opérationnelle terminée,Commencez à appeler del Relâchez la serrure.,C'est là que index3 Verrouillage, Cause index3 Les affaires de 1s Il a été libéré par quelqu'un d'autre.
Ce qui équivaut finalement à une situation sans serrure
a Au moment de l'opération , Libération automatique après un délai de verrouillage ;Après libération,b Saisir la serrure pour l'opération ;En ce momentaOpération terminée,Verrouillage manuel,Ça vabLa serrure de,b Si vous relâchez encore la serrure, une erreur se produira
Résolution: setnx Lors de l'acquisition de la serrure,Définir une valeur unique spécifiée(Par exemple:uuid); Obtenez ceci avant de libérer Valeurs,Déterminer si votre propre serrure
Quatre、OptimisationlockParamètresUUIDPrévention des erreurs et des suppressions
Cinq、UtiliserLUALe script garantit l'atomicité de la suppression
UtiliserlockDeuuid Il est possible de libérer d'autres serrures dans une certaine mesure , Mais cela ne résout pas entièrement la situation .Parce que la comparaisonuuidEt supprimerlockCe n'est pas atomique
Questions: aComparaisonuuidAprès passage, Verrouillage expiré libération automatique ,bRe - lock,a Ceci se libère manuellement bVerrouillage, C'est toujours un problème
Résolution: UtiliserLUA Le script garantit l'atomicité de la suppression
LUAScript:
Sera complexe ou en plusieurs étapes redis Fonctionnement,Écris comme un script,Soumis une fois redis Mise en œuvre,Réduire les connexions répétées redis Nombre de fois,Améliorer les performances
LUA Le script est similaire redis Services,Avec une certaine atomicité,Ne pas être mis en file d'attente par d'autres ordres,Ça pourrait être faitredis Transactionnel
@GetMapping("testLockLua")
public void testLockLua() {
//1 Déclarez un uuid ,Ce sera un value Dans notre key Parmi les valeurs correspondantes
String uuid = UUID.randomUUID().toString();
//2 Définir une serrure:lua Le script peut utiliser la même serrure,Pour supprimer!
String skuId = "25"; // Accès à skuId Pour 25 Article No. 100008348542
String locKey = "lock:" + skuId; // Les données de chaque article sont verrouillées
// 3 Obtenir la serrure
Boolean lock = redisTemplate.opsForValue().setIfAbsent(locKey, uuid, 3, TimeUnit.SECONDS);
// Première catégorie: lock Aucun Code n'est écrit entre la date d'expiration.
// redisTemplate.expire("lock",10, TimeUnit.SECONDS);//Définir le délai d'expiration
// Si true
if (lock) {
// Début de la logique opérationnelle mise en œuvre
// Obtenir dans le cache num Données
Object value = redisTemplate.opsForValue().get("num");
// S'il est vide, retournez directement
if (StringUtils.isEmpty(value)) {
return;
}
// Pas vide. S'il y a une anomalie ici! Alors delete La suppression a échoué! Ce qui veut dire que la serrure existe toujours!
int num = Integer.parseInt(value + "");
// Faire num Chaque fois+1 Mise en cache
redisTemplate.opsForValue().set("num", String.valueOf(++num));
/*Utiliser lua Script pour verrouiller*/
// Définition lua Script: Les opérations de jugement et de suppression seront effectuées simultanément
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
// Utiliser redis Mise en œuvre lua Mise en œuvre
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(script);
// Définissez le type de valeur de retour Pour Long
// Parce qu'en supprimant le jugement,Retour à 0,Encapsuler comme type de données.Si elle n'est pas encapsulée, la valeur par défaut est retournée String Type,
// Renvoie la chaîne avec 0 Il y aura des erreurs.
redisScript.setResultType(Long.class);
// Le premier est exécuté script Script ,La deuxième chose à juger key,Le troisième est key La valeur correspondante.
redisTemplate.execute(redisScript, Arrays.asList(locKey), uuid);
} else {
// D'autres fils attendent
try {
// Sommeil
Thread.sleep(1000);
// Après s'être réveillée,Méthode d'appel.
testLockLua();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Pour s'assurer que les serrures distribuées sont disponibles,Nous devons au moins nous assurer que la mise en œuvre de la serrure satisfait simultanément aux quatre conditions suivantes:
- Exclusivité mutuelle;À tout moment,Un seul client peut tenir la serrure
- Il n'y aura pas d'impasse;Même si un client s'est écrasé pendant qu'il tenait la serrure sans déverrouiller activement,Il peut également s'assurer que d'autres clients peuvent verrouiller(ParamètreslockDate d'expiration)
- La sonnerie doit être éteinte.;Le verrouillage et le déverrouillage doivent être du même client,Le client lui - même ne peut pas déverrouiller les serrures des autres(UtiliserLUAScripts etuuid)
- Le verrouillage et le déverrouillage doivent être atomiques(UtiliserLUAScript)
边栏推荐
猜你喜欢
The sharp drop in electricity consumption in Guangdong shows that the substitution of high-tech industries for high-energy consumption industries has achieved preliminary results
How to maintain the laptop battery
How to solve the keyboard key failure of notebook computer
Stegano in the world of attack and defense
【Hot100】19. Delete the penultimate node of the linked list
今天14:00 | 港大、北航、耶鲁、清华、加大等15位ICLR一作讲者精彩继续!
Introduction to software engineering - Chapter 6 - detailed design
软件工程导论——第六章——详细设计
Guide for high-end programmers to fish at work
【观察】数字化时代的咨询往何处走?软通咨询的思与行
随机推荐
红队第8篇:盲猜包体对上传漏洞的艰难利用过程
What is the digital transformation of manufacturing industry
程序员职业生涯真的很短吗?
Are you still using charged document management tools? I have a better choice! Completely free
How to use F1 to F12 correctly on laptop keyboard
Exclusive news: Alibaba cloud quietly launched RPA cloud computer and has opened cooperation with many RPA manufacturers
Red team Chapter 10: ColdFusion the difficult process of deserializing WAF to exp to get the target
数据库系统原理与应用教程(004)—— MySQL 安装与配置:重置 MySQL 登录密码(windows 环境)
Tutorial on the principle and application of database system (005) -- Yum offline installation of MySQL 5.7 (Linux Environment)
Endeavouros mobile hard disk installation
Why is the pkg/errors tripartite library more recommended for go language error handling?
博睿数据一体化智能可观测平台入选中国信通院2022年“云原生产品名录”
MLPerf Training v2.0 榜单发布,在同等GPU配置下百度飞桨性能世界第一
AI高考志愿填报:大厂神仙打架,考生付费围观
如何使用phpIPAM来管理IP地址和子网
芯片供应转向过剩,中国芯片日产增加至10亿,国外芯片将更难受
Alibaba cloud, Zhuoyi technology beach grabbing dialogue AI
游戏行业安全选择游戏盾,效果怎么样?
巴比特 | 元宇宙每日必读:奈雪币、元宇宙乐园、虚拟股票游戏...奈雪的茶这波“操作拉满”的营销活动你看懂了吗?...
瑞典公布决定排除华为5G设备,但是华为已成功找到新出路