Bloqueo distribuido (basado en la implementación de Redis)

Nota de operación: después de ingresar al redisson de github, seleccione la siguiente imagen para ingresar a la introducción del proyecto Redisson (documento chino)Inserte la descripción de la imagen aquí

Uno, el concepto de cerraduras distribuidas

El propósito de los bloqueos distribuidos es: en un entorno distribuido, para que una determinada operación (insertar un dato de la base de datos) se ejecute solo una vez, para evitar una serie de problemas causados ​​por operaciones de datos repetidas, el comando setnx y lua en Los Redis se utilizan Script para implementar bloqueos distribuidos para resolver los problemas anteriores.

Dos, varias situaciones de uso del comando setnx

2.1 ¿Qué debo hacer si hay una excepción en el código comercial y el comando para ejecutar el bloqueo de liberación (eliminar bloqueo) no se puede ejecutar, lo que resulta en un interbloqueo (el bloqueo no se libera)?

La solución es: intente {} finalmente {} se puede usar para resolver el problema, pero si el código comercial se ejecuta y la máquina pierde energía repentinamente, ¿qué debo hacer?
La solución final es: establecer el tiempo de vencimiento del bloqueo, incluso si el bloqueo no se elimina, el bloqueo vencido se eliminará automáticamente
Inserte la descripción de la imagen aquí

2.2. El parpadeo (tiempo de inactividad) entre el establecimiento del bloqueo y el establecimiento del tiempo de vencimiento seguirá siendo un punto muerto ¿Cómo solucionarlo?

La solución es: use el comando setnx ex de Redis, que es una combinación de configuración de bloqueo + configuración de tiempo de vencimiento, y también es una operación atómica.

Inserte la descripción de la imagen aquí

2.3. Al eliminar el candado, debido al tiempo de espera del código comercial, el candado caduca antes y el candado de otra persona se elimina, ¿qué debo hacer?
2.4. Si el negocio se agota, otros subprocesos también se bloquearán y entrarán en la operación comercial, lo que resultará en operaciones comerciales repetidas.

Resuelva el problema anterior: al ocupar la cerradura, establezca el valor en uuid, al eliminar, compare

Inserte la descripción de la imagen aquí

2.5. Dado que se compara el valor de uuid (para obtener el valor de Redis) y se elimina el valor, no se trata de una operación atómica. Al obtener el valor de uuid, puede llevar mucho tiempo, lo que da como resultado la eliminación final de el bloqueo de otro hilo. ¿Qué debo hacer?

Solución: compare el valor uuid + eliminar el valor después de una comparación exitosa = operación atómica, puede saberlo en el documento oficial de Redis, puede usar el script lua

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

2.6. La forma final es la siguiente: Al bloquear y desbloquear, asegúrese de atomicidad

Inserte la descripción de la imagen aquí
Código final:

 @Test
    public void testRedisHadoop(){
    
    
        String uuid = UUID.randomUUID().toString();
//        占锁(设置值),并且设置过期时间。这是一个Redis的原子命令
//        NX和EX
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);

        if(lock){
    
    
//            加锁成功,执行业务
            try{
    
    
                System.out.println("业务执行。。。。");
            }finally {
    
    
                //            获取值对比+对比成功处理=原子操作------lua脚本
//            通过uuid来删除锁,以防删除别人的锁或者
//            String lockValue = (String) redisTemplate.opsForValue().get("lock");
//            if(uuid.equals(lockValue)){
    
    
//                redisTemplate.delete("lock");
//            }

                //lua脚本
                String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                        "then\n" +
                        "    return redis.call(\"del\",KEYS[1])\n" +
                        "else\n" +
                        "    return 0\n" +
                        "end";

                //删除锁
                Object lock1 = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList("lock"), uuid);

            }




        }else {
    
    
            System.out.println("获取锁失败,继续尝试");
            testRedisHadoop();//自旋锁
        }


    }

Tres, cerradura distribuida de Redisson -------- cerradura reentrante

Si se llama al método b en el método a, a agrega un candado marcado como 1 yb también agrega un candado marcado como 1.
Si es un ** bloqueo reentrante, entonces cuando se ejecuta el método a, el método b interno no necesita esperar a que a libere el bloqueo, y utiliza directamente el bloqueo del método a.
Si se trata de un
bloqueo no reentrante, ** entonces, cuando se ejecuta el método a, el método b interno debe esperar a que a libere el bloqueo 1 antes de tomar el bloqueo 1, y luego ejecutarlo.

3.1. Dos métodos de bloqueo y recarga para cerraduras reentrantes (consulte la figura siguiente)

Inserte la descripción de la imagen aquí

Cuatro, bloqueo de lectura y escritura de redis

La función es: obtener los datos más recientes

El bloqueo de escritura es un bloqueo exclusivo (bloqueo de exclusión mutua, bloqueo exclusivo), el bloqueo de lectura es un bloqueo compartido.

Cuando el bloqueo de escritura está en funcionamiento, el bloqueo de lectura solo puede esperar. Si no hay ningún bloqueo de escritura en funcionamiento, el bloqueo de lectura se comparte, al igual que sin bloqueo.

Inserte la descripción de la imagen aquí

4.2. Descripción complementaria del bloqueo de lectura-escritura

Leer + escribir: hay un bloqueo de lectura y la escritura debe esperar. ======= Cuando el bloqueo de lectura está en curso, el bloqueo de escritura debe esperar a que se libere el bloqueo de lectura (la ejecución está completa) antes de que pueda ejecutarse.
Leer + Leer: Equivalente al estado desbloqueado. Todos los bloqueos de lectura actuales se bloquearán correctamente al mismo tiempo.
Escribir + Leer: Leer bloqueo y esperar a que se libere el bloqueo de escritura
Escribir + Escribir: Modo de bloqueo (debe obtener hasta)
Resumen: Mientras haya un bloqueo de escritura, debe esperar.

Cinco, el bloqueo de redis

Inserte la descripción de la imagen aquí

Seis, semáforo redis (semáforo)

6.1. Principios básicos de uso:

Inserte la descripción de la imagen aquí

6.2. Se puede utilizar para limitar la corriente, el principio específico es el siguiente:

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_43983411/article/details/110679363
Recomendado
Clasificación