Redis面试题(四)

文章目录

  • 前言
  • 一、锁互斥机制
  • 二、watch dog 自动延期机制
  • 三、 可重入加锁机制
  • 四、释放锁机制
  • 五、 上述 Redis 分布式锁的缺点
  • 六、使用过 Redis 分布式锁么,它是怎么实现的?
  • 总结


前言

  1. 锁互斥机制
  2. watch dog 自动延期机制
  3. 可重入加锁机制
  4. 释放锁机制
  5. 上述 Redis 分布式锁的缺点
  6. 使用过 Redis 分布式锁么,它是怎么实现的?

`

一、锁互斥机制

那么在这个时候,如果客户端 2 来尝试加锁,执行了同样的一段 lua 脚本,会咋样呢?很简单,第一个 if 判断会执行“exists myLock”,发现 myLock 这个锁 key 已经存在了。接着第二个 if 判断,判断一下,myLock 锁 key 的 hash 数据结构中,是否包含客户端 2 的 ID,但是明显不是的,因为那里包含的是客户端 1 的 ID。
所以,客户端 2 会获取到 pttl myLock 返回的一个数字,这个数字代表了 myLock 这个锁 key的 剩余生存时间。比如还剩 15000 毫秒的生存时间。此时客户端 2 会进入一个 while 循环,不停的尝试加锁。


二、watch dog 自动延期机制

客户端 1 加锁的锁 key 默认生存时间才 30 秒,如果超过了 30 秒,客户端 1 还想一直持有这把锁,怎么办呢?
简单!只要客户端 1 一旦加锁成功,就会启动一个 watch dog 看门狗, 他是一个后台线程,会每隔 10 秒检查一下,如果客户端 1 还持有锁 key,那么就会不断的延长锁 key 的生存时间。


三、 可重入加锁机制

那如果客户端 1 都已经持有了这把锁了,结果可重入的加锁会怎么样呢?比如下面这种代码:
这时我们来分析一下上面那段 lua 脚本。 第一个 if 判断肯定不成立,“exists myLock”会显示锁key 已经存在了。 第二个 if 判断会成立,因为 myLock 的 hash 数据结构中包含的那个 ID,就是客户端 1 的那个 ID,也就是“8743c9c0-0795-4907-87fd-6c719a6b4586:1”
此时就会执行可重入加锁的逻辑,他会用:
incrby myLock 8743c9c0-0795-4907-87fd-6c71a6b4586:1 1 ,通过这个命令,对客户端 1的加锁次数,累加 1。此时 myLock 数据结构变为下面这样:
大家看到了吧,那个 myLock 的 hash 数据结构中的那个客户端 ID,就对应着加锁的次数


四、释放锁机制

如果执行 lock.unlock(),就可以释放分布式锁,此时的业务逻辑也是非常简单的。其实说白了,就是每次都对 myLock 数据结构中的那个加锁次数减 1。如果发现加锁次数是 0 了,说明这个客户端已经不再持有锁了,此时就会用:“del myLock” 命令,从 redis 里删除这个 key。
然后呢,另外的客户端 2 就可以尝试完成加锁了。这就是所谓的 分布式锁的开源 Redisson 框架的实现机制。
一般我们在生产系统中,可以用 Redisson 框架提供的这个类库来基于 redis 进行分布式锁的加锁与释放锁。

五、 上述 Redis 分布式锁的缺点

其实上面那种方案最大的问题,就是如果你对某个 redis master 实例,写入了 myLock 这种锁key 的 value,此时会异步复制给对应的 master slave 实例。但是这个过程中一旦发生 redis master 宕机,主备切换,redis slave 变为了 redis master。
接着就会导致,客户端 2 来尝试加锁的时候,在新的 redis master 上完成了加锁,而客户端 1
也以为自己成功加了锁。此时就会导致多个客户端对一个分布式锁完成了加锁。这时系统在业务语义上一定会出现问题, 导致各种脏数据的产生。
所以这个就是 redis cluster,或者是 redis master-slave 架构的主从异步复制导致的 redis 分布式锁的最大缺陷:在 在 redis master 实例宕机的时候,可能导致多个客户端同时完成加锁。


六、使用过 Redis 分布式锁么,它是怎么实现的?

先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。
如果在 setnx 之后执行 expire 之前进程意外 crash 或者要重启维护了,那会怎么样?
set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和 expire 合成一条指令来用的!


总结

  1. 锁互斥机制
  2. watch dog 自动延期机制
  3. 可重入加锁机制
  4. 释放锁机制
  5. 上述 Redis 分布式锁的缺点
  6. 使用过 Redis 分布式锁么,它是怎么实现的?

你可能感兴趣的:(面试,redis,数据库,缓存)