Solo debes bloquear Redis

Hablando de bloqueos de Redis, las siguientes tres se consideran las palabras más frecuentes:

  • Setnx
  • RedLock
  • Redisson

 

Setnx

 

El comando Setnx al que se hace referencia comúnmente en la actualidad no solo se refiere al comando de valor clave de Redis setnx.

 

Generalmente se refiere al uso del comando Establecer más el parámetro NX en Redis. El comando Establecer actualmente admite muchos parámetros opcionales:

SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]

 

Por supuesto, no escribiré la API en silencio en el artículo. Los parámetros básicos aún no están claros, por lo que puede ir al sitio web oficial.

La figura anterior es el principio general de Setnx elaborado por el autor. Se basa principalmente en la característica de que su clave no existe para establecerse correctamente. El proceso A obtiene la cerradura. Cuando la clave de la cerradura no se elimina, el proceso B naturalmente falla para adquirir la cerradura.

 

Entonces, ¿por qué usar PX 30000 para establecer un período de tiempo de espera? Me temo que el proceso A no es razonable y el bloqueo no se ha liberado. Si colapsa, el bloqueo se quitará directamente y nadie en el sistema obtendrá el bloqueo.

Aun así, todavía no hay garantía de infalibilidad. Si el proceso A no es razonable y los recursos en el bloqueo de la operación exceden el período de tiempo de espera establecido por el autor, entonces otros procesos obtendrán el bloqueo. Cuando el proceso A regrese, la respuesta es eliminar los bloqueos de otros procesos, como se muestra en la figura:

En la imagen de ahora, el tiempo T5 se cambia al tiempo de espera de bloqueo, que es liberado por Redis.

 

El proceso B obtiene felizmente el bloqueo en T6 y tarda menos de un tiempo. El proceso A finaliza la operación y devuelve un Del para liberar el bloqueo.

 

Cuando se completa la operación del proceso B y se libera el bloqueo (en el momento T8 en la figura):

 

De hecho, no está mal que no se pueda encontrar el bloqueo.Si un proceso C llega a bloquearse con éxito en T7, entonces el proceso B libera el bloqueo del proceso C.

 

Por analogía, el proceso C puede liberar el bloqueo del proceso D, el proceso D .... (Se prohíben las muñecas), se desconocen las consecuencias específicas.

 

Por lo tanto, al usar Setnx, aunque Key es la función principal, Value no puede estar inactivo. Puede establecer una ID de cliente única o usar un número aleatorio como UUID.

 

Al desbloquear, primero obtenga Valor para determinar si es un bloqueo agregado por el proceso actual y luego elimínelo. Código falso:

String uuid = xxxx;
// 伪代码,具体实现看项目中用的连接工具
// 有的提供的方法名为set 有的叫setIfAbsent
set Test uuid NX PX 3000
try{
// biz handle....
} finally {
    // unlock
    if(uuid.equals(redisTool.get('Test')){
        redisTool.del('Test');
    }
}

 

¿Parece estable esta vez? Por el contrario, esta vez el problema es más obvio: en el bloque de código final, Get y Del no son operaciones atómicas, y aún existen problemas de seguridad en los procesos.

 

¿Por qué hay tantas preguntas? Hay dos razones:

  • Solo aclarando las desventajas podemos mejorarlo mejor.
  • Muchas empresas todavía utilizan el último fragmento de código anterior.

 

Paradoja de artículos grandes y pequeños:

Las grandes empresas implementan estándares, pero aunque las pequeñas empresas y los pequeños proyectos no son rigurosos, la concurrencia no es alta y la probabilidad de problemas es tan baja como la de las grandes empresas.

 

 

 

Entonces, una de las posturas correctas para eliminar el bloqueo es usar scripts de Lua para ejecutar los comandos eval / evalsha de Redis:

-- lua删除锁:
-- KEYS和ARGV分别是以集合方式传入的参数,对应上文的Test和uuid。
-- 如果对应的value等于传入的uuid。
if redis.call('get', KEYS[1]) == ARGV[1] 
    then 
    -- 执行删除操作
        return redis.call('del', KEYS[1]) 
    else 
    -- 不成功,返回0
        return 0 
end

 

La razón para asegurar la atomicidad a través de scripts de Lua es un poco más popular: incluso si escribe flores en Lua, la ejecución es ejecutada por un comando (eval / evalsha). Si un comando no se ejecuta, otros clientes no pueden verlo.

 

Entonces, dado que es tan problemático, ¿existe una herramienta mejor? Hablemos de Redisson.

 

Antes de presentar Redisson, el autor explica brevemente por qué el valor predeterminado de Setnx actual se refiere al comando Establecer con parámetros NX, en lugar de referirse directamente al comando Setnx.

 

Debido a que la versión de Redis es anterior a la 2.6.12, Set no admite los parámetros de NX. Si desea completar un bloqueo, necesita dos comandos:

1. setnx Test uuid
2. expire Test 30

 

Es decir, introducir la clave y establecer el período de validez son dos pasos separados: en teoría, habrá 1 justo después de la ejecución, el programa se cuelga y no se puede garantizar la atomicidad.

 

Pero ya en 2013, es decir, hace 7 años, Redis lanzó la versión 2.6.12, y el sitio web oficial (página de comando Establecer) también declaró que "SETNX, SETEX, PSETEX pueden quedar obsoletos en versiones futuras y eliminarlo permanentemente".

 

El autor una vez leyó un artículo de un tipo grande. Entre ellos, hay una pequeña rutina de entrevista que guía a los principiantes. El texto específico se olvida. Probablemente signifique lo siguiente: Cuando se trata de bloqueos de Redis, puedes comenzar con Setnx primero, y luego extraerlo lentamente Puede agregar parámetros al comando Establecer para reflejar su propio conocimiento.

 

Si ha leído este artículo por destino y ha aprendido esta rutina, como autor de este artículo, me gustaría agregar un recordatorio: ¡Preste atención a sus años de trabajo! Primero responda al comando que el sitio web oficial indica que está a punto de ser descartado, y luego introduzca las "nuevas funciones" del comando Set hace siete años. Si alguien que acaba de graduarse dijo esto, el entrevistador pensará que se ha ido mediante.

Tú haces el entrevistador, el entrevistador también lo hará tú.  


- vt · Wozkistock

 

Redisson

 

Redisson es uno de los clientes de Redis de Java y proporciona algunas API para facilitar el funcionamiento de Redis.

 

Pero el cliente de Redisson es un poco poderoso. El autor ha cortado solo una parte de la imagen en el sitio web oficial:

Se puede decir que esta lista de características es demasiado. ¿Has visto algunos nombres de clases en el paquete JUC? Redisson nos ayudó a hacer una versión distribuida.

 

Por ejemplo, AtomicLong, simplemente use RedissonAtomicLong directamente, ni siquiera necesita recordar el nombre de la clase, que es muy fácil de usar.

 

El bloqueo es solo la punta de su iceberg y, desde su página Wiki, admite los modos maestro-esclavo, centinela, clúster y otros. Por supuesto, el modo de nodo único definitivamente es compatible.

 

Este artículo todavía se centra en las cerraduras y los demás no se presentarán. El código fuente de implementación de bloqueo común de Redisson es principalmente RedissonLock. Aquellos que no hayan visto su código fuente, pueden querer echar un vistazo.

 

Las operaciones de bloqueo / liberación de bloqueo en el código fuente se realizan con scripts de Lua, el paquete es muy completo y funciona de inmediato.

Aquí hay un pequeño detalle. El bloqueo se puede lograr usando Setnx. ¿Es innecesario usar scripts Lua?

 

El autor también lo pensó muy rigurosamente: ¿Cómo puede una cosa tan poderosa escribir código de desecho?

 

De hecho, el autor echó un vistazo más de cerca. El script de Lua para bloquear y desbloquear es muy completo, incluida la reentrada del bloqueo. Se puede decir que esto es muy reflexivo. También escribí el código para probarlo:

De hecho, es tan suave como ReentrantLock de JDK, por lo que Redisson se ha implementado tan bien, ¿qué es RedLock?

 

RedLock

 

 

El chino de RedLock se traduce literalmente y se llama RedLock. Red Lock no es una herramienta, sino un algoritmo de bloqueo distribuido propuesto oficialmente por Redis.

 

En Redisson, que se acaba de presentar, se implementó la versión RedLock del bloqueo. En otras palabras, además del método getLock, también existe el método getRedLock.

 

El autor probablemente dibujó la comprensión del candado rojo:

Si no está familiarizado con la implementación de alta disponibilidad de Redis, está bien. Aunque el algoritmo RedLock requiere varias instancias, estas instancias se implementan de forma independiente y no existe una relación maestro-esclavo.

 

El autor de RedLock señaló que la razón para usar independiente es evitar la pérdida de bloqueo causada por la replicación asincrónica de Redis. Por ejemplo, si el nodo maestro no llega y los datos simplemente se establecen en el nodo esclavo, se cuelga.

 

¿Alguna gente piensa que los grandes son buenos con las palancas, pensando en situaciones extremas todos los días? De hecho, tiene una alta disponibilidad, es el 99,999 ...% de los dígitos después del punto decimal.

 

Volviendo a la imagen simple de arriba, el algoritmo de candado rojo cree que siempre que 2N + 1 nodos se bloqueen con éxito, entonces se considera que el bloqueo se ha adquirido y todas las instancias se desbloquean al desbloquear.

 

El proceso es:

  • Solicitar bloqueos de cinco nodos en secuencia
  • Inferir si se debe omitir el nodo en función de un cierto período de tiempo de espera
  • Los tres nodos se bloquean con éxito y el tiempo empleado es menor que el período de validez del bloqueo
  • Confirma que el bloqueo es exitoso

 

En otras palabras, asumiendo que el bloqueo expira en 30 segundos, y tomó 31 segundos bloquear los tres nodos, es natural que el bloqueo fallara.

 

Este es solo un ejemplo. De hecho, no debe esperar tanto tiempo para cada nodo. Como se indica en el sitio web oficial, suponiendo que el período de validez es de 10 segundos, el período de tiempo de espera de una sola operación de instancia de Redis debe estar entre 5 y 50 milisegundos (tenga en cuenta la unidad de tiempo).

 

Supongamos que establecemos el período de validez en 30 segundos y que dos nodos de Redis han agotado el tiempo de espera en la figura. Luego, el nodo que bloqueó con éxito el bloqueo tomó 3 segundos en total, por lo que el período de validez real del bloqueo es de menos de 27 segundos.

 

Es decir, se deducen los 3 segundos para bloquear correctamente las tres instancias, y también se deduce el tiempo total de espera por el tiempo de espera de la instancia de Redis. Al ver esto, es posible que tenga algunas preguntas sobre este algoritmo, entonces no está solo.

 

Mira la descripción de Red Lock en el sitio web oficial de Redis. En la parte inferior de esta página de descripción, puedes ver la famosa pelea de hadas sobre Red Lock.

El debate de RedLock entre Martin Kleppmann y Antirez. Uno es un arquitecto distribuido altamente calificado y el otro es el padre de Redis.

 

Las personas oficialmente vinculadas son las más letales. Es broma, si la pregunta se puede incluir en el sitio web oficial, debe ser valiosa.

 

Entonces, si desea utilizar Red Lock en su proyecto, además de la introducción de Red Lock, también puede leer dos artículos más, a saber:

  • Mensaje de interrogación de Martin Kleppmann

  • Puesto de contraataque de Antirez

Supongo que te gusta

Origin blog.csdn.net/baidu_39322753/article/details/104943302
Recomendado
Clasificación