Redis分布式锁如何实现——简单理解版

目录

前言

满足条件

加锁之后产生的问题

避免死锁的方法

Lua脚本实现避免释放其他锁

看门狗判断过期

扩展

Lua脚本

Redission


前言

在如今开发的某些项目中,多个进程必须以互斥的方式独占共享资源,这时用分布式锁是最直接有效的,分布式锁发展至今,已经有越来越多的项目普及了,也已经被面试官拿出来提问,所以今天我们可以一起来学习一下分布式锁

满足条件

想要实现分布式锁,前提就需要满足如下几个条件

  • 互斥性,在任意时刻,只有一个客户端能持有锁

  • 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端可以加锁

  • 加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了,即不能误解锁

  • 具有容错性。只要大多数Redis节点正常运行,客户端就能获取和释放锁

Redis实现分布式锁主要利用Redis的setnx命令。setnx是SET if not exists(如果不存在,则set)的简写,我们使用Redis时,一般会采用主从集群+哨兵的模式部署,哨兵的作用就是监测redis节点的运行状态。普通的主从模式,当master崩溃时,需要手动切换让slave成为master,使用主从+哨兵结合的好处在于,当master异常宕机时,哨兵可以实现故障自动切换,把slave提升为新的master,继续提供服务,以此保证可用性。

加锁之后产生的问题

但是当加上锁之后,就会有新的问题产生出来,当Redis或者客户端突然运行异常,或者突然宕机之后,我们添加的锁无法及时释放出来;又或者是我们执行程序时突然业务逻辑错误,无法释放出锁,那么就会导致后续操作无法进行,出现死锁的情况这个时候我们就需要想方法来解决如何避免死锁了

避免死锁的方法

如果要避免死锁,我们首先就是想到的Redis可以设置过期时间,让这个进程在规定时间之后就可以自己释放掉,从而避免了死锁的风险,这个时候我们就又有了新的问题------你怎么知道你释放的锁是你想释放的锁,你怎么知道他什么时候不用了,你要释放它。这个时候我们又会认识到两个新成员了:Lua脚本和看门狗

Lua脚本实现避免释放其他锁

首先知道Redis是单线程执行的,当执行一个线程时其他线程都无法执行,所以我们可以写一个lua脚本,在脚本里先试用GET请求,利用Redis键值对的特性根据i线程id获取到自己那条线程,然后执行SET命令(强制获取到锁,执行这条命令的概率很低),最后执行DEL命令删除线程,从而避免删除掉其他线程

看门狗判断过期

在Redis中,开发者已经想到这个情况,所以Redis里面已经改有一个很好的方法判断过期了,他就是redission(看门狗),Redisson是一个Java语言实现的Redis SDK客户端,在使用分布式锁时,它就采用了自动续期的方案来避免锁过期,这个守护线程我们一般叫它看门狗线程。这个SDK提供的API非常友好,它可以像操作本地锁一样操作分布式锁。客户端一旦加锁成功,就会启动一个watch dog看门狗线程,它是一个后台线程,会每隔一段时间(这段时间的长度与设置的锁的过期时间有关)检查一下,如果检查时客户端还持有锁key(也就是说还在操作共享资源),那么就会延长锁key的生存时间。

想到这些问题,Redis分布式锁大家应该就理解了

扩展

Lua脚本

lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

想要了解更多可以去Redis 使用lua脚本最全教程_redis lua语法-CSDN博客中了解更多

Redission

相关推荐
憨憨睡不醒啊6 分钟前
如何让LLM智能体开发助力求职之路——构建属于你的智能体开发知识体系📚📚📚
面试·程序员·llm
勤奋的知更鸟8 分钟前
Java编程之原型模式
java·开发语言·原型模式
叶 落18 分钟前
[Java 基础]数组
java·java 基础
KK溜了溜了19 分钟前
JAVA-springboot log日志
java·spring boot·logback
珂朵莉MM21 分钟前
2021 RoboCom 世界机器人开发者大赛-高职组(初赛)解题报告 | 珂学家
java·开发语言·人工智能·算法·职场和发展·机器人
香蕉炒肉36 分钟前
Java优化:双重for循环
java·开发语言
傍晚冰川1 小时前
FreeRTOS任务调度过程vTaskStartScheduler()&任务设计和划分
开发语言·笔记·stm32·单片机·嵌入式硬件·学习
PingdiGuo_guo1 小时前
C++智能指针的知识!
开发语言·c++
黄雪超1 小时前
JVM——打开JVM后门的钥匙:反射机制
java·开发语言·jvm
有梦想的攻城狮1 小时前
spring中的@RabbitListener注解详解
java·后端·spring·rabbitlistener