redis应用---分布式锁

文章来源

https://wudashan.cn/2017/10/23/Redis-Distributed-Lock-Implement/#releaseLock-wrongDemo2

分布式锁实现方式

    数据库乐观锁

    redis分布锁

    zookeeper分布式锁

 

可靠性:

    1、互斥性。在任意时刻,只有一个客户端能持有锁

    2、不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。

    3、具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁

    4、加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了

 

 

加锁操作:

     

//获取分布式锁
function lock($redis,$key,$value)
{
    //如果不存在key就设置,并且设置超时时间为10秒,防止死锁
    if($redis->set($key,$value,['nx','ex'=>10]) == 'ok'){
        return true;
    }
    return false;
}

上述操作结果:

    1. 当前没有锁(key不存在),那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。

    2. 已有锁存在,不做任何操作

 

解锁操作:

function unlock($redis,$key,$value)
{
$script = 
<<<EOF
if redis.call('get',KEYS[1]) == KEYS[2]
then
    return redis.call('del',KEYS[1])
else
    return 0
end
EOF;
return $redis->eval($script,[$key,$value],2);
}

 

测试代码

<?php
$redis = new Redis(); 
$redis->connect('127.0.0.1');


//定义加锁方法





//定义解锁方法









$key = 'key';
$value = time()+rand(0,100);//随机值,确定以后解锁来自同一客户端
if(lock($redis,$key,$value)){
    // 业务逻辑     todo

    //测试并发情况下,只能有一个客户端成功上锁,并执行减操作

     if($redis->get('num') > 0){
         $redis->decr('num');
     }

   //解锁
   unlock($redis,$key,$value);
}

 

posted @ 2018-04-27 12:03  rcj_飞翔  阅读(84)  评论(0)    收藏  举报