Problemas y soluciones comunes de bloqueo distribuido de Redis
1.2 Los bloqueos deben tener tiempos de espera para evitar interbloqueos
1.3 Crear bloqueos y configurar tiempos de espera de bloqueo requieren atomicidad
1.4 Actualización de tiempos de espera de bloqueo
1.5 El bloqueo de B es liberado por A
1.6 Bloqueo reentrante
1.7 Bloqueo distribuido bajo el clúster
Explicación del problema:
En primer lugar, los bloqueos distribuidos resuelven el problema de los bloqueos distribuidos. De hecho, el principio de bloqueo y desbloqueo es el mismo que el de un solo proceso. Un solo proceso debe considerar el problema de que varios subprocesos acceden y modifican la misma variable para garantizar que varios subprocesos no accedan a la misma variable. Al mismo tiempo, es necesario seguir el orden en que se modifican las variables. Bloqueo al acceder a las variables. Este bloqueo puede ser un bloqueo pesado o cas basado en un bloqueo optimista.
Solución:
Utilice el comando redis setnx (establecido si no existe). Este comando solo puede ser ocupado por un cliente si hay una clave única en la instancia de redis. desea establecer un valor en la clave será rechazado.
Explicación del problema:
La liberación del bloqueo de Redis requiere la operación del cliente. Si el cliente se bloquea repentinamente, no habrá ninguna operación para liberar el bloqueo, lo que significa que otros clientes quieren volver a abrirlo. -lock., pero el problema no se puede agregar.
Solución:
Por lo tanto, para evitar el problema de que el cliente se cuelgue o que el cliente no pueda liberar el bloqueo, debe agregar un tiempo de espera al bloqueo al mismo tiempo.
Por lo tanto, para evitar el problema de que el cliente se cuelgue o que el cliente no pueda liberar el bloqueo correctamente, debe agregar un tiempo de espera al bloqueo mientras agrega el cerrar con llave.
En otras palabras, agregar un bloqueo y agregar un tiempo de espera al bloqueo se puede realizar de la siguiente manera:
>setnx lockkey true #Agregar operación de bloqueo
OK
>expire lockkey 5 #Agregar un tiempo de espera al bloqueo
... Haz algunas cosas clave...
>del lockkey #Libera el bloqueo
(entero) 1
Explicación del problema:
Como se puede ver en la configuración de bloqueo y tiempo de espera 2.3, se requieren dos comandos para completar las operaciones setnx y expirar, es decir, se requieren dos operaciones RTT.
Solución:
Utilice el comando set extension
de la siguiente manera:
>set lockkey true ex 5 nx ?# Lock, 5 segundos Después de la invalidación
OK
... haz algunas cosas clave...
>del lockkey
Lo anterior establece lockkey verdadero ex El comando 5 nx completa setnx y expira al mismo tiempo, resolviendo así el problema de atomicidad.
Explicación del problema:
El bloqueo distribuido de Redis caduca, pero la lógica empresarial no se ha ejecutado. Sin embargo, aquí hay una forma diferente de pensar sobre el problema y el tiempo de vencimiento. Se cambia el bloqueo de Redis. ¿No se solucionaría si fuera más largo? Esto sigue siendo un problema. Podemos ajustar manualmente la duración del tiempo de vencimiento del bloqueo de Redis al agregar un bloqueo, pero ¿cuánto tiempo es apropiado? El tiempo de ejecución de la lógica empresarial es incontrolable y un ajuste excesivo afectará el rendimiento operativo.
Solución:
Utilice el cliente redisson. redisson resuelve algunos problemas espinosos de redis en un entorno distribuido. Su propósito es permitir a los usuarios prestar menos atención a Redis y dedicar más energía. procesamiento de lógica de negocios. Redisson tiene una buena encapsulación de bloqueos distribuidos y solo necesita llamar a la API.
RLock lock = redissonClient.getLock("stockLock");
Después de que el registro del bloqueo sea exitoso, redisson tendrá una tarea programada para monitorear el bloqueo y verificarlo cada 10 segundos si el bloqueo aún se mantiene. Sí, se renovará una vez después de su vencimiento. El tiempo de vencimiento predeterminado es 30 segundos. Este mecanismo también se llama "vigilancia"
Explicación del problema:
Dos subprocesos A y B intentan bloquear la clave myLock. El subproceso A adquiere el bloqueo primero (si el bloqueo expira en 3 segundos). más tarde), el hilo B espera para intentar obtener el bloqueo, hasta el momento no hay problema. En este momento, si la lógica empresarial consume mucho tiempo y el tiempo de ejecución ha excedido el tiempo de vencimiento del bloqueo de Redis, el bloqueo del subproceso A se liberará automáticamente (la clave se elimina) y el subproceso B detecta que la clave myLock no existe y ejecuta el comando SETNX. Obtuve el bloqueo. Pero en este momento, después de que el subproceso A termine de ejecutar la lógica empresarial, aún liberará el bloqueo (eliminará la clave), lo que hará que el subproceso A libere el bloqueo del subproceso B.
?Solución:
?En términos generales, debemos traer un valor único para identificar cada hilo al agregar un candado y solo liberar la clave con el valor especificado, de lo contrario ocurrirá Escena caótica de apertura de cerradura. Generalmente, podemos establecer este valor en prefix_current_thread_id o uuid del negocio, y solo los subprocesos con el mismo valor actual pueden liberar el bloqueo.
Explicación del problema:
Arriba. Como dijimos, necesitamos usar setnx para asegurarnos de que el bloqueo sea único y luego elegimos el comando set para configurar el bloqueo y el tiempo de espera. Durante el tiempo que queremos bloquear, el cliente propietario del bloqueo quiere obtenerlo nuevamente, es decir, reingresar el bloqueo
Solución:
Establecer el bloqueo en el hash del estructura de número de bloqueos, el número de bloqueos cada vez es +1
Explicación del problema:
El problema es que esta situación ocurre en el escenario del clúster de Redis. De hecho, ahora para garantizar la alta disponibilidad y el rendimiento de acceso de Redis, se configurarán un nodo maestro de Redis y un nodo esclavo. El nodo maestro es responsable de las operaciones de escritura y el nodo esclavo es responsable de las operaciones de lectura. que todos nuestros bloqueos deben escribirse en la instancia del servidor redis maestro, si el servidor redis principal falla, los recursos se liberarán (sin persistencia, el problema será más complicado si se agrega persistencia). El problema será más complicado). En este momento, los datos del nodo maestro de Redis no se han copiado al servidor esclavo. En este momento, otros clientes aprovecharán la oportunidad para adquirir el bloqueo y el cliente que anteriormente poseía el bloqueo. lock aún puede operar el recurso. En este momento, ocurrirán múltiples problemas. El cliente accede al mismo recurso y realiza operaciones.
Solución:
Utilice el candado rojo, cuyo principio es el mismo que el candado distribuido del cuidador del zoológico. Si más de la mitad de los hosts se configuran correctamente, la adquisición del bloqueo es exitosa. Cabe señalar que la cantidad de hosts debe ser impar, pero este es un problema eficiente