Redis的锁来缓解并发请求
本文最后更新于:4 年前
Redis 锁 缓解并发
- 简单实现- Redis 锁主要利用 Redis 的 setnx 命令实现 - 加锁命令:SETNX key value,当键不存在时,对键进行设置操作并返回成功,否则返回失败。KEY 是锁的唯一标识,一般按业务来决定命名。
 - 解锁命令:DEL key,通过删除键值对释放锁,以便其他线程可以通过 SETNX 命令来获取锁。
- 锁超时:EXPIRE key timeout, 设置 key 的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。
 - 代码编写: - 1 
 2
 3
 4
 5
 6- if (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
 23- while (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 协议 ,转载请注明出处!