Un artículo sobre bloqueos distribuidos de Redis

Bloqueo distribuido Redis

¿Qué es un bloqueo distribuido?

El bloqueo distribuido de Redis es un mecanismo de bloqueo basado en Redis, que se utiliza para controlar el acceso simultáneo a los recursos compartidos en un entorno distribuido multiconcurrente . Cuando varias aplicaciones o procesos acceden a un recurso compartido, el bloqueo distribuido puede garantizar que solo un proceso pueda acceder al recurso y que no se produzcan incoherencias de datos ni condiciones de carrera.

¿Por qué necesita bloqueos distribuidos?

En un entorno de subprocesos múltiples, si varios subprocesos acceden a recursos compartidos al mismo tiempo, como pedidos para llevar e inventario de productos, se producirá una competencia de datos, lo que dará como resultado datos sucios o productos sobrevendidos.

Por ejemplo, suponga que hay 100 usuarios que participan en una actividad de venta flash por tiempo limitado, y cada usuario está limitado a comprar 1 artículo, y la cantidad de artículos es solo 3. Sin acceso exclusivo mutuo a los recursos compartidos, pueden ocurrir las siguientes situaciones:

  • Múltiples subprocesos, como el subproceso 1, 2 y 3, ingresan al método de compra al mismo tiempo, y cada subproceso corresponde a un usuario.
  • El subproceso 1 consulta la cantidad que el usuario ha comprado y descubre que el usuario actual no ha comprado y todavía hay un producto en stock, por lo que cree que el proceso de compra puede continuar.
  • El subproceso 2 también ejecuta la consulta de la cantidad que el usuario ha comprado y descubre que el usuario actual no ha comprado y todavía hay 1 producto en stock, por lo que cree que el proceso de compra puede continuar.
  • El subproceso 1 continúa, disminuye la cantidad de existencias en 1 y devuelve el éxito.
  • El subproceso 2 continúa la ejecución, disminuye la cantidad de inventario en 1 y devuelve el éxito.
  • En este momento, ocurrió el problema de sobreventa, lo que resultó en una copia adicional del producto que se estaba vendiendo.

inserte la descripción de la imagen aquí

Para garantizar que se acceda a los recursos compartidos de manera segura, debemos usar operaciones de exclusión mutua para proteger los recursos compartidos, es decir, solo un subproceso puede acceder a los recursos compartidos a la vez, y otros subprocesos deben esperar a que se libere el subproceso actual antes de acceder. De esta forma, se pueden evitar carreras de datos y problemas de datos sucios, y se puede garantizar la corrección y estabilidad del programa.

¿Cómo se puede lograr el acceso exclusivo mutuo a los recursos compartidos? El bloqueo es una solución más general, más precisamente un bloqueo pesimista.

El bloqueo pesimista siempre asume el peor de los casos, pensando que habrá problemas cada vez que se acceda a un recurso compartido (por ejemplo, se modifiquen los datos compartidos), por lo que se bloqueará cada vez que adquiera una operación de recurso, para que otros subprocesos quieran obtener este recurso, se bloqueará hasta que el titular anterior libere el bloqueo. Es decir, los recursos compartidos solo los usa un subproceso a la vez, otros subprocesos se bloquean y los recursos se transfieren a otros subprocesos después de su uso .

Para subprocesos múltiples autónomos, en Java, generalmente usamos los bloqueos nativos de JDK, como ReetrantLockclases y palabras clave , para controlar el acceso de múltiples subprocesos en un proceso JVM a recursos locales compartidos.synchronized

inserte la descripción de la imagen aquí

En la figura se puede ver que estos subprocesos que acceden a los recursos compartidos son mutuamente excluyentes, y solo un subproceso puede adquirir un bloqueo local para acceder a los recursos compartidos al mismo tiempo.

En un sistema distribuido, diferentes servicios/clientes generalmente se ejecutan en procesos JVM separados. Si varios procesos de JVM comparten el mismo recurso, no hay forma de lograr un acceso mutuamente exclusivo a los recursos mediante bloqueos locales. Así nacieron los candados distribuidos .

La siguiente figura muestra la situación de agregar bloqueos locales en un sistema distribuido.
inserte la descripción de la imagen aquí

En este momento, debido a que el bloqueo sincronizado se implementa en función de la JVM, pero cada servidor tiene su propia JVM, por lo que sincronizado no puede controlar varios subprocesos en este momento.

La siguiente figura muestra el uso de bloqueos distribuidos.

inserte la descripción de la imagen aquí

​ Cuando estaba leyendo esta parte, vi que alguien mencionó en el bombardeo que los bloqueos distribuidos son para permitir que varias máquinas virtuales jvm compitan por el mismo bloqueo. Creo que los bloqueos distribuidos son fáciles de entender si lo piensas de esta manera.

¿Qué condiciones deben tener los bloqueos distribuidos?

Un bloqueo distribuido básico debe cumplir con:

  • Exclusión mutua : en cualquier momento, el bloqueo solo puede ser mantenido por un subproceso.
  • Alta disponibilidad : el servicio de bloqueo tiene una alta disponibilidad. Cuando un servicio de bloqueo falla, puede cambiar automáticamente a otro servicio de bloqueo. Además, incluso si hay un problema con la lógica del código del bloqueo de liberación del cliente, el bloqueo finalmente se liberará, lo que no afectará el acceso de otros subprocesos a los recursos compartidos. Esto generalmente se logra a través de un mecanismo de tiempo de espera.
  • Reentrante : después de que un nodo adquiere el bloqueo, puede volver a adquirirlo.

Además de las tres condiciones básicas anteriores, un buen bloqueo distribuido también debe cumplir las siguientes condiciones:

  • Alto rendimiento : la operación de adquisición y liberación de bloqueos debe completarse rápidamente y no debe tener un gran impacto en el rendimiento de todo el sistema.
  • No bloqueo : Si no se puede obtener el bloqueo, no puede esperar indefinidamente para evitar afectar el funcionamiento normal del sistema.

Implementación de bloqueos distribuidos

Redis implementa bloqueos distribuidos principalmente mediante el uso del comando setnx de Redis. setnx es CONFIGURADO SI NO EXISTE (crear si no existe).

  • adquirir bloqueo

    #添加锁  NX是互斥  EX是设置超时时间
    SET lock value NX EX 10
    
  • liberar bloqueo

    DEL lock
    

inserte la descripción de la imagen aquí

Cómo Redis implementa bloqueos distribuidos para controlar la duración efectiva

1. Estimación basada en el tiempo de ejecución del negocio (generalmente no utilizado, inexacto).

2. Establezca un tiempo de vencimiento para el bloqueo y renuévelo después de que la empresa exceda el tiempo de vencimiento.

¿Cómo proceder con la renovación?

Redisson es un cliente Redis de lenguaje Java de código abierto que proporciona muchas funciones listas para usar.

Redisson proporciona un mecanismo de vigilancia (watchdog) Si el subproceso que opera los datos compartidos no completa el negocio dentro del tiempo de vencimiento, Watch Dog continuará extendiendo el tiempo de adquisición del bloqueo. Esto asegura que el bloqueo no se liberará debido a un tiempo de espera.
inserte la descripción de la imagen aquí

En las operaciones generales de bloqueo, generalmente establecemos que cuando un hilo adquiere un bloqueo, si otro hilo quiere adquirir el bloqueo, interrumpirá el hilo para que no pueda adquirir el bloqueo. Sin embargo, se proporciona un mecanismo de espera en redisson, que es el bucle while de la figura anterior.Después de adquirir el bloqueo, otro subproceso intenta adquirirlo continuamente, de modo que si el subproceso 1 completa el negocio en un período corto de tiempo, el subproceso 2 puede ejecutar el negocio inmediatamente después de adquirir el bloqueo en un bucle en este momento, lo que reduce el tiempo de espera y mejora la eficiencia de la ejecución del negocio.

¿La implementación de Redisson de bloqueos distribuidos es reentrante?

Redisson implementa bloqueos distribuidos que son reentrantes. El llamado bloqueo reentrante significa que el mismo bloqueo se puede adquirir varias veces en un subproceso. Por ejemplo, un subproceso está ejecutando un método con un bloqueo, y otro método que requiere el mismo bloqueo se llama en el método. Luego, el subproceso puede ejecutar directamente el método llamado para volver a ingresar sin volver a adquirir el bloqueo. como en Java synchronized``ReentrantLock.

El principio de reentrada del bloqueo distribuido de redisson es que mantiene una estructura hash internamente.

public void add1(){
    
    
RLock lock = redissonClient.getLock(“heimalock"); 
boolean isLock = lock.tryLock();
//执行业务
add2(); 
//释放锁
lock.unlock();
}
public void add2(){
    
    
RLock lock = redissonClient.getLock(“heimalock");
boolean isLock = lock.tryLock();
//执行业务
//释放锁
lock.unlock();
}

inserte la descripción de la imagen aquí

Resumir

  • ¿Cómo implementar el bloqueo distribuido de Redis?

    En Redis, puede usar el comando SET combinado con la opción NX (SET IF NOT EXISTS) para implementar bloqueos distribuidos. Estos son los pasos básicos de implementación:

    1. Adquirir un bloqueo: cuando un proceso necesita adquirir un bloqueo, envía un comando SET a Redis, establece una clave específica como la identidad del bloqueo y establece el tiempo de vencimiento. Los parámetros clave son los siguientes:

      • El nombre de la clave de la cerradura: por lo general, un identificador único que se utiliza para identificar la cerradura.
      • Valor de bloqueo: puede ser un valor único generado aleatoriamente que se utiliza para distinguir diferentes procesos.
      • Tiempo de caducidad: asegúrese de que incluso si el bloqueo no se libera explícitamente, caducará automáticamente después de un cierto período de tiempo para evitar interbloqueos.

      Por ejemplo, adquiera un candado con:

      #添加锁  NX是互斥  EX是设置超时时间
      SET lock value NX EX 10
      

      Si la clave no existe, es decir, el bloqueo no ha sido ocupado por otros procesos, el bloqueo se adquiere con éxito y se devuelve OK; si la clave existe, el bloqueo ya está ocupado por otros procesos, y la adquisición del bloqueo falla, devolviendo cero.

    2. Liberar bloqueo: cuando un proceso termina de operar en un recurso compartido, debe liberar el bloqueo para permitir que otros procesos adquieran el bloqueo. El proceso de liberación de un bloqueo consta de los siguientes dos pasos:

      • Eliminar bloqueo: El proceso elimina la clave del bloqueo y libera el recurso de bloqueo ejecutando el comando DEL
      DEL lock
      
  • ¿Cómo usar Redis para darse cuenta de la duración efectiva del bloqueo?

    Se utiliza el marco Redisson en Redis. Redisson debe bloquearse manualmente. Puede configurar el tiempo de vencimiento del bloqueo y el tiempo de espera. Cuando una empresa supera el tiempo de vencimiento del bloqueo, se introduce un mecanismo de vigilancia Watch Dog en Redisson. Verificará si la empresa aún mantiene el bloqueo a intervalos regulares. Si aún mantiene el bloqueo, aumente el tiempo de espera del bloqueo y libere el bloqueo cuando se complete el negocio.

    En las operaciones generales de bloqueo, generalmente establecemos que cuando un hilo adquiere un bloqueo, si otro hilo quiere adquirir el bloqueo, interrumpirá el hilo para que no pueda adquirir el bloqueo. Sin embargo, Redisson proporciona una máquina de espera.Después de que se adquiere el bloqueo, otro subproceso intenta adquirirlo continuamente, de modo que si el subproceso 1 completa el negocio en un período corto de tiempo, el subproceso 2 puede ejecutar el negocio inmediatamente después de adquirir el bloqueo en un bucle en este momento, lo que reduce el tiempo de espera y mejora la eficiencia de la ejecución del negocio.

  • ¿Es el bloqueo de reentrada implementado por Redisson un bloqueo de reentrada?

    Es reentrante El principio reentrante del bloqueo distribuido de Redisson es que mantiene una estructura hash en su interior. Determine si es un bloqueo retenido por el subproceso actual, si es así, cuente los bloqueos retenidos por el subproceso actual y disminuya el valor en la estructura hash en uno si se libera el bloqueo.

La mayoría de las imágenes de este artículo son del ppt de Dark Horse, que se toman prestadas aquí. Artículos de Redis-10-principio de implementación de bloqueo distribuido de Redis (setnx, redisson)_哔哩哔哩_bilibili

Supongo que te gusta

Origin blog.csdn.net/weixin_52340450/article/details/131708576
Recomendado
Clasificación