Varias implementaciones de bloqueo de redis

1. Clasificación de bloqueo de Redis

  1. Redis uso de la tabla de puntos es un comando de bloqueo INCR, SETNX,SET

2. El primer comando de bloqueoINCR

La idea de este bloqueo es que si la clave no existe, el valor de la clave se inicializará a 0 primero, y luego se ejecutará la operación INCR para incrementar en uno. 
Luego, cuando otros usuarios realizan la operación INCR y aumentan en uno, si el número devuelto es mayor que 1, significa que se está utilizando el bloqueo.

1、 客户端A请求服务器获取key的值为1表示获取了锁

2、 客户端B也去请求服务器获取key的值为2表示获取锁失败

3、 客户端A执行代码完成,删除锁

4、 客户端B在等待一段时间后在去请求的时候获取key的值为1表示获取锁成功

5、 客户端B执行代码完成,删除锁


$redis->incr($key);

$redis->expire($key, $ttl); //设置生成时间为1秒

 

3. El segundo candadoSETNX

La idea del bloqueo es que si la clave no existe, establezca la clave en valor, 
si la clave ya existe,  SETNX no se tomará ninguna acción.

 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

 客户端A执行代码完成,删除锁

 客户端B在等待一段时间后在去请求设置key的值,设置成功

 客户端B执行代码完成,删除锁


$redis->setNX($key, $value);

$redis->expire($key, $ttl);

4. El tercer juego de cerradura

Existe un problema con los dos métodos anteriores. Verá que debe configurar la clave para que caduque. Entonces, ¿por qué establecer la caducidad de la clave? Si la ejecución de la solicitud sale inesperadamente por algún motivo, lo que hace que el bloqueo se cree pero no se elimine, el bloqueo siempre existirá, por lo que la caché nunca se actualizará en el futuro. Por lo tanto, debemos agregar un tiempo de vencimiento a la cerradura para evitar accidentes. 
Sin embargo, configurar con Expire no es una operación atómica. Así que también puedes usar transacciones para asegurar la atomicidad , pero aún hay algunos problemas, por lo que el funcionario citó otro.El uso del comando SET en sí ha incluido la función de establecer el tiempo de vencimiento desde la versión 2.6.12.

1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

3、 客户端A执行代码完成,删除锁

4、 客户端B在等待一段时间后在去请求设置key的值,设置成功

5、 客户端B执行代码完成,删除锁


$redis->set($key, $value, array('nx', 'ex' => $ttl)); //ex表示秒

5. Otras cuestiones

Aunque el paso anterior ha satisfecho nuestras necesidades, ¿todavía necesita considerar otros problemas? 
1. ¿Qué debo hacer si redis descubre que el bloqueo falla? ¿Solicitud de interrupción o solicitud cíclica? 
2. En el caso de solicitud circular, si uno adquiere la cerradura, ¿es posible agarrar la cerradura cuando el otro adquiere la cerradura? 
3. Una vez que el bloqueo expira por adelantado, el cliente A no ha terminado de ejecutarse, y luego el cliente B ha adquirido el bloqueo. En este momento, el cliente A ha terminado de ejecutarse, ¿se eliminará el bloqueo de B al eliminar el bloqueo?

6. Solución

Para la pregunta 1: use la solicitud de bucle, la solicitud de bucle para obtener el bloqueo. Para la 
pregunta 2: para el segundo problema, cuando la solicitud de bucle obtenga el bloqueo, agregue la función de suspensión y espere unos milisegundos para ejecutar el bucle. Para el 
problema 3: al bloquear el La clave depositada es aleatoria. En este caso, cada vez que elimine la clave, juzgue si el valor almacenado en la clave es el mismo que el almacenado por usted mismo.

do { //针对问题1,使用循环

$timeout = 10;

$roomid = 10001;

$key = 'room_lock';

$value = 'room_'.$roomid; //分配一个随机的值针对问题3

$isLock = Redis::set($key, $value, 'ex', $timeout, 'nx');//ex 秒

if ($isLock) {

if (Redis::get($key) == $value) { //防止提前过期,误删其它请求创建的锁

//执行内部代码

Redis::del($key);

continue;//执行成功删除key并跳出循环

}

} else {

usleep(5000); //睡眠,降低抢锁频率,缓解redis压力,针对问题2

}

} while(!$isLock)

7. Otro candado

Los bloqueos anteriores satisfacen completamente las necesidades, pero el funcionario también proporciona un conjunto de algoritmos de bloqueo, aquí está PHP como ejemplo

$servers = [

['127.0.0.1', 6379, 0.01],

['127.0.0.1', 6389, 0.01],

['127.0.0.1', 6399, 0.01],

];


$redLock = new RedLock($servers);


//加锁

$lock = $redLock->lock('my_resource_name', 1000);


//删除锁

$redLock->unlock($lock)

El anterior es un método de bloqueo oficial, que es el mismo que el sexto método, excepto que el oficial es más robusto. Entonces puedes usar directamente el método de clase oficial para llamar. El funcionario proporciona cómo implementar bloqueos en varios idiomas.

Supongo que te gusta

Origin blog.csdn.net/qq_27828675/article/details/110850631
Recomendado
Clasificación