¿El candado distribuido de Redis que todo el mundo admira es realmente infalible?
La solución anterior tiene un problema fatal, es decir, después de que un subproceso adquiere el bloqueo, no puede realizar la operación de desbloqueo normalmente debido a algunos factores anormales (como el tiempo de inactividad), por lo que el bloqueo nunca se liberará. . Para hacer esto, podemos agregar un tiempo de espera a este bloqueo. La primera vez que pensamos en los segundos clave EXPIRE de Redis. Pero aquí no podemos usar EXPIRE para implementar bloqueos distribuidos, porque puede ocurrir una excepción entre las dos operaciones y SETNX y aún no se logran los resultados esperados.
Para esto, el enfoque correcto debería ser utilizar el comando "establecer valor clave [ex segundos] [px millones] [NX | xx]".
A partir de la versión Redis 2. 6. 12, el comportamiento del comando SET se puede modificar a través de una serie de parámetros: EX segundos: Establece el tiempo de caducidad de la clave en segundos. El efecto de ejecutar el valor de la clave SET EX segundos es equivalente a ejecutar el valor de los segundos de la clave SETEX. PX milisegundos: establezca el tiempo de caducidad de la clave en milisegundos. El efecto de ejecutar el valor clave establecido px mills es equivalente a ejecutar el valor clave psetex. NX: establezca la clave solo si la clave no existe. Ejecutar el valor de la clave SET NX tiene el mismo efecto que ejecutar el valor de la clave SETNX. XX: establezca la clave solo si la clave ya existe.
¿Ejecutar valor clave de configuración PX? El efecto en milisegundos equivale al valor de milisegundos de la clave PSETEX para completar. NX: solo deja de configurar y manipular claves si ya no existen. Las consecuencias de ejecutar el valor de la clave SET NX son equivalentes a ejecutar el valor de la clave SETNX. XX: Deje de configurar y manipular claves solo si la clave alguna vez existió. Por ejemplo, si necesitamos crear un bloqueo distribuido y establecer el tiempo de vencimiento en 10 segundos, podemos completar el siguiente orden:
Aquí podemos ver el problema de un vistazo: GET y DEL son dos independientes Operación, puede ocurrir una excepción entre la ejecución de GET y la ejecución de DEL. Si nos aseguramos de que el código desbloqueado sea atómico, podemos resolver el problema. Aquí presentamos un nuevo método, el script Lua. Al desbloquear, todavía usamos el comando DEL para desbloquear.
El plan revisado parece perfecto, pero en realidad todavía hay problemas. Supongamos que un subproceso A adquiere un bloqueo y establece el tiempo de caducidad en 10 segundos, y luego se necesitan 15 segundos para ejecutar la lógica empresarial. En este momento, el mecanismo de caducidad de Redis liberó automáticamente el bloqueo obtenido por el subproceso A. Después de que el hilo A adquiere el bloqueo y pasa 10, es posible que otros hilos hayan adquirido el cambio en el bloqueo. Cuando el subproceso A ejecuta la lógica empresarial y se prepara para desbloquear (tecla DEL), es posible eliminar el bloqueo adquirido por otros subprocesos. En términos generales, los bloqueos distribuidos de Redis no son infalibles.