Redis如何实现分布式锁

目录

获取锁:

释放锁:

Lua脚本:

Redisson


分布式锁是,满足分布式系统或集群模式下多进程可见并且互斥的锁,因为我们熟知的java中的锁只是在单体架构下单个jvm中才会生效,如果部署了多个jvm则会导致新的并发问题。

对于分布式锁我们要确保的五个基本特征:多进程可见性、互斥性、高可用、高性能和安全性

分布式锁的实现常见的有三种:Mysql、Redis和Zookeeper

这里说一下redis实现分布式锁的操作

获取锁:

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

非阻塞式:尝试一次,成功返回true,失败返回false

释放锁:

代码层面实现一下:

获取锁,键设置成业务名字(这里拼接了两个字符串),值的话设置成线程id,并设置超时时间

释放锁:

直接删除即可

这种情况还是会出现一些问题

在极端情况下,如果线程1获取到锁,但是线程1发生了阻塞,阻塞期间锁超时释放,然后此时线程2获取到锁,线程1又醒了之后将线程2获取的锁释放了,这时候线程3又进来了,又会出现线程问题

结局思路就是,在释放锁的时候将储存的线程id取出来(上锁的时候值已经存为线程id),判断是否为当前线程,如果不是就不能释放,只有是当前线程自己的锁才能释放id。

但是这种情况又会在分布式和集群下出现问题,因为线程id是在jvm中维护的一个递增数,解决办法是生产一个uuid拼接线程号表示线程标识,后续判断使用这个新的唯一标识。

当然,到这里还没完

如果当线程1判断锁是否为自己之后,在准备释放锁的过程中线程阻塞,然后锁超时释放,这时候别的线程2来获得到锁,线程1阻塞结束,就还是会把线程2的锁释放掉,这里就需要确保一下操作的原子性,

Lua脚本:

这里Redid的事务只能确保原子性,无法保证事务的一致性,这里通过lua脚本实现

lua脚本教程地址可参考:Lua 教程 | 菜鸟教程

脚本执行redsi命令可以通过如下命令来实现

复制代码
redis.call('set','name','jack') 等价于redis中的set name call

Redis调用lua脚本如下

脚本也可以通过参数传递,如下:

通过lua脚本实现如下功能

lua脚本如下:

再Java中可以通过redisTemplate调用lua脚本,通过execute方法

使用时可以新建一个lua脚本文件,将脚本写入,然后通过DefaultRedisScript的setLocation方法设置脚本位置

然后通过redisTemplate调用execute执行脚本,将脚本和参数传入,这就实现了判断+释放锁代码的原子性,将多行代码变成了一行

当然给予setnx的分布式锁还是存在下面问题:

  1. 不可重入:同一个无法多次获得同一把锁
  2. 不可重试:获取锁只尝试一次就返回,没有重试机制
  3. 超时释放:超时释放虽然可以避免死锁,但是如果业务时间耗时较长,也会导致锁释放,存在安全隐患
  4. 主从一致性:如果redis提供了主从集群,主从同步存在延迟,当主宕机时,如果从同步主中的锁数据回出现问题

为了解决这些问题,redisson提供的这些服务,点击下方跳转redisson笔记

Redisson

Redisson实现分布式锁(看门狗机制)-CSDN博客

相关推荐
不能只会打代码5 分钟前
边缘视频分析平台的架构设计与性能优化——从750ms到190ms的调优之路
java·spring boot·redis·性能优化·边缘计算·物联网竞赛
xufengzhu3 小时前
第三方 Python 库 redis-py + hiredis 的使用
开发语言·redis·python
轻刀快马6 小时前
跨越软硬件的共鸣(二):从 Cache 写策略看 Redis 与 DB 的一致性博弈
java·开发语言·redis·计算机组成原理
ACP广源盛139246256737 小时前
GSV5600@ACP#多接口协议转换芯片,物理 AI 便携终端的互联核心
大数据·人工智能·分布式·嵌入式硬件·spark
lazy H8 小时前
Spring Boot 项目如何连接 Redis?新手入门配置和常见错误总结
ide·spring boot·redis·后端·学习·intellij-idea
木雷坞9 小时前
Firecrawl Docker Compose 自托管排查:镜像、Redis、队列和 Playwright
redis·docker·容器·firecrawl
柏舟飞流10 小时前
Spring Boot 进阶实战:整合 MyBatis、Redis、JWT,搭一个更像真实项目的后端服务
spring boot·redis·mybatis
南部余额11 小时前
Canal解决MySQL与Redis数据一致性问题
数据库·redis·mysql·canal·数据·数据同步
典学长编程12 小时前
Redis分布式缓存超详细教学(微服务版)!
redis·微服务·持久化·主从复制·redis哨兵集群
极客先躯12 小时前
高级java每日一道面试题-2026年02月12日-实战篇[Docker]-什么是容器的 Seccomp 配置?如何自定义?
java·运维·分布式·docker·容器·自动化·文件