Redis的锁来缓解并发请求
本文最后更新于:4 年前
Redis 锁 缓解并发
简单实现
Redis 锁主要利用 Redis 的 setnx 命令实现
- 加锁命令:SETNX key value,当键不存在时,对键进行设置操作并返回成功,否则返回失败。KEY 是锁的唯一标识,一般按业务来决定命名。
- 解锁命令:DEL key,通过删除键值对释放锁,以便其他线程可以通过 SETNX 命令来获取锁。
- 锁超时:EXPIRE key timeout, 设置 key 的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。
代码编写:
1
2
3
4
5
6if (Redis::setnx("my:lock", 1)) {
Redis::expire("my:lock", 10);
// ... do something
Redis::del("my:lock")
}官方推荐的写法(建议用这种写法):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23while (true)
{
if(redisLock($token))
{
//业务内容
unlock($token);
break;
}
}
function redisLock($token)
{
return Redis::set("my:lock", $token, "ex", "5", "nx");
}
function unlock($token)
{
$script = "if redis.call('get',KEYS[1]) == ARGV[1]
then return redis.call('del',KEYS[1])
else return 0
end";
return Redis::eval($script,1,'my:lock',$token);
}- 这里的 token 是一个随机数,当 lock 的时候,往 redis 的 my:lock 中存的是这个 token,unlock 的时候,先 get 一下 lock 中的 token,如果和我要删除的 token 是一致的,说明这个锁是之前我 set 的,否则的话,说明这个锁已经过期,是别人 set 的,我就不应该对它进行任何操作。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!