Maison >base de données >Redis >Comment implémenter le verrouillage distribué Redis

Comment implémenter le verrouillage distribué Redis

尚
original
2019-06-29 10:43:4625201parcourir

Comment implémenter le verrouillage distribué Redis

Verrouillage distribué Redis :
1. Principe de mise en œuvre
Utilisez la commande set dans Redis pour implémenter le verrouillage distribué.

À partir de la version 2.6.12 de Redis, set peut utiliser les paramètres suivants :

SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]

EX seconde : Réglez le délai d'expiration de la clé sur secondes. L'effet de la valeur de clé SET EX seconde est équivalent à la valeur de seconde clé SETEX.
PX milliseconde : définissez le délai d'expiration de la clé sur millisecondes millisecondes. Valeur de clé SET L'effet milliseconde PX est équivalent à la valeur milliseconde de la clé PSETEX.
NX : La clé est définie uniquement lorsque la clé n'existe pas. L'effet de la valeur de clé SET NX est équivalent à la valeur de clé SETNX.
XX : définissez la clé uniquement lorsque la clé existe déjà.
Valeur de retour :
SET ne retournera OK que lorsque l'opération de réglage est terminée avec succès.
Si NX ou XX est défini, mais que l'opération de configuration n'est pas exécutée car les conditions ne sont pas remplies, la commande renvoie une réponse groupée NULL.
Commande :
> SET key value EX ttl NX

L'idée générale est :
(a) SET lock currentTime+expireTime EX 600 NX, utilisez set pour définir la valeur de verrouillage et définir l'expiration Le temps est de 600 secondes. En cas de succès, le verrou est acquis

(b) Après l'acquisition du verrou, si le nœud se déconnecte, la valeur de verrouillage expirera automatiquement à l'heure d'expiration
; (c) Lorsque le verrou est libéré, utilisez del pour supprimer la valeur de la clé de verrouillage ;
L'utilisation d'une machine autonome Redis pour les services de verrouillage distribués peut entraîner des problèmes ponctuels, entraînant une mauvaise disponibilité du service. les exigences de stabilité sont élevées, il est officiellement recommandé d'utiliser des clusters Redis (tels que 5 Si plus de 3 demandes de verrouillage réussies sont obtenues, le verrou est considéré comme acquis) pour implémenter le verrouillage distribué Redis. Voir RedLock pour plus de détails.
2. Avantages
Hautes performances, Redis peut être conservé et les données ne sont pas facilement perdues ;
La méthode de cluster Redis améliore la stabilité.
3. Inconvénients
Certaines données peuvent être perdues lors de l'utilisation de la commutation maître-esclave Redis.
4. Implémentation open source
Implémentation open source de la version python : python-redis-lock.

La méthode d'implémentation spécifique du verrouillage distribué Redis :

La méthode de verrouillage et de déverrouillage :

private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final Long RELEASE_SUCCESS = 1L; 

    /**
     * 尝试获取分布式锁
     * @param lockKey 锁
     * @param requestId 请求标识
     * @param expireTime 超期时间
     * @return 是否获取成功
     */
    public Boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
        Jedis jedis = this.jedisPool.getResource();
        String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
        if (LOCK_SUCCESS.equals(result)) {
            return true;
        }
        return false;

    }

     /**
     * 释放分布式锁
     * @param lockKey 锁
     * @param requestId 请求标识
     * @return 是否释放成功
     */
    public Boolean releaseDistributedLock(String lockKey, String requestId) {
        Jedis jedis = this.jedisPool.getResource();
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
        if (RELEASE_SUCCESS.equals(result)) {
            return true;
        }
        return false;

    }

Applications spécifiques

try{
String requestId = UUID.randomUUID().toString();
Boolean flag = tryGetDistributedLock(lock,requestId,1000);
int n = 0;
while(!flag){
      //如果没有获取锁,可以尝试下一个lock,如果都没有,则尝试 n 次,退出
     ...
     if(n++>5){ throw new Exception("尝试获取锁失败");}  
     ...  
}
if(!flag){
throw new Exception("尝试获取锁失败");
}
}catch(){
}finally{
    releaseDistributedLock(lock,requestId);
}

Pour plus de connaissances sur Redis, veuillez visiter la colonne

Tutoriel d'utilisation de Redis !

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:
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