当前位置: 首页 > news >正文

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

 

相关文章:

  • 2025信创即时通讯排行:安全合规与生态适配双轮驱动
  • oracle事务的组成
  • uniapp vue3使用uniapp的生命周期
  • 借助AI Agent实现数据分析
  • 触动精灵对某东cookie读取并解密--记lua调用C语言
  • 基于粒子群算法(PSO)栅格地图移动机器人路径规划
  • MySQL错误 “duplicate entry ‘1‘ for key ‘PRIMARY‘“ 解决方案
  • Axure大屏可视化模板:赋能多领域,开启数据展示新篇章
  • AF3 quat_multiply 和 quat_multiply_by_vec 函数解读
  • PostgreSQL用SQL实现俄罗斯方块
  • EasyRTC轻量级Webrtc音视频通话SDK,助力带屏IPC在嵌入式设备中的应用
  • 密码协议与网络安全——引言
  • UE5.5 Niagara 渲染器
  • 从 0 到 1 构建 Python 分布式爬虫,实现搜索引擎全攻略
  • 简述Mybatis的插件运行原理,以及如何编写一个插件?
  • 【Ratis】Ratis Streaming概览
  • win11找不到hosts文件该如何处理
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.3.21)
  • 以欧洲极端降水归因分析为例讲解CESM模型在降水诊断计算中的科研应用
  • 性能优化中如何“避免链接关键请求”
  • 泽连斯基拒绝普京72小时停火提议,坚持应尽快实现30天停火
  • 5名中国公民在美国交通事故中遇难
  • 中国驻旧金山总领馆:领区发生旅行交通事故,有中国公民伤亡
  • 受天气等影响SC8041航班三次备降延误超12小时,山航致歉
  • 旭辉控股集团:去年收入477.89亿元,长远计划逐步向轻资产业务模式转型
  • “五一”看什么?这里有一份申城视听指南