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); }

浙公网安备 33010602011771号