Redis实战15-Redis实现分布式锁思路

  • 作者: 凯哥Java(公众号:凯哥Java)
  • Redis
  • 时间:2023-04-02 19:13
  • 2806人已阅读
简介 在上一篇文章中(Redis实战14-分布式锁基本原理和不同实现方式对比),我们介绍了为什么在集群或者分布式环境下,JVM级别的锁会失效,什么是分布式锁,分布式锁需要满足哪些条件以及实现分布式锁的三种常见方案,同时对三种实现方案做了对比。那么本文,咱们就来讲讲基于Redis实现分布式锁思路。实现分布式锁时候,需要实现两个基本的方法获取锁和释放锁获取锁获取锁时候需要考虑互斥和非阻塞。互斥:确保只能有一

🔔🔔好消息!好消息!🔔🔔

 如果您需要注册ChatGPT,想要升级ChatGPT4。凯哥可以代注册ChatGPT账号代升级ChatGPT4

有需要的朋友👉:微信号 kaigejava2022

在上一篇文章中(Redis实战14-分布式锁基本原理和不同实现方式对比),我们介绍了为什么在集群或者分布式环境下,JVM级别的锁会失效,什么是分布式锁,分布式锁需要满足哪些条件以及实现分布式锁的三种常见方案,同时对三种实现方案做了对比。那么本文,咱们就来讲讲基于Redis实现分布式锁思路。

实现分布式锁时候,需要实现两个基本的方法

获取锁和释放锁

获取锁

获取锁时候需要考虑互斥和非阻塞。

互斥:确保只能有一个线程获取锁;

在Redis中获取锁,利用的是shetNx的互斥特性

253597b09190a2985b31058d7c685eca.png

演示setnx命令:

ddad4d33a5ebeaa5a63d869acc6991cb.png

非阻塞:尝试异常,成功返回true.失败返回false.

释放锁

手动释放:

d78d75984a37d6ce77ceddd8d23d899e.png

a4f7ac06e1c00689d0b539c8bdddc0b7.png

如果在手动释放的时候,服务宕机了怎么办?可以添加一个超时释放

超时释放:获取锁时候添加一个超时时间

setnx的时候添加expire命令

74611932a1fa4cb2668d35e796344965.png

命令演示:

120c9b49b7d2029857fe53c4fa621b0e.png

思考:这两个命令真的就万无一失了吗?答案是:否

假设在执行setnx的时候成功了,但是在执行expire命令的时候服务宕机了,那么是不是就没有个锁设置过期时间了。所以,我们需要保证setnx和expire命令要么同时成功,要么同时失败。也就是要保证这两个命令原子性。其实Redis的set命令有还有很多参数,我们使用help命令查询下set的命令帮助:

9e40f48f0473533f8374d77319618f46.png

根据上图,我们可以看到,set的时候可以ex和nx两个命令一起使用。演示:

238da418cb1b574540762e0eb44db55a.png

思考:如果在set ex nx失败后,我们应该怎么做?

我们来回顾下jdk中提供的锁,其实有两种处理方案。一种是阻塞的,获取不到锁就一直阻塞等待,等到锁被释放为止;还有一种非阻塞等待的,就是,获取不到锁,就直接返回结果,而不是一直等待下去。根据这个思想,我们使用Redis分布式锁,使用非阻塞的。

总结

我们再来看看流程。如下图:

a777a15d87a14b863c954ae36615e359.png

下一篇预告:基于Redis实现分布式锁初级版本。

凯哥推荐Redis实现分布式锁系列文章:

《Redis实战11-实现优惠券秒杀下单》

《Redis实战12-优惠券实现一人一单功能》

《Redis实战13-集群下线程并发安全问题》

《Redis实战14-分布式锁基本原理和不同实现方式对比》

《Redis实战15-Redis实现分布式锁思路》

或者到凯哥个人博客(聪明的你,从结束语中应该能知道地址)查看Redis系列教程

c

结束语

大家好,我是凯哥Java(kaigejava),乐于分享技术文章,欢迎大家关注“凯哥Java”,及时了解更多。让我们一起学Java。也欢迎大家有事没事就来和凯哥聊聊~~~


TopTop