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

分布式锁(Redission)

分布式锁:

使用场景:

通常对于一些使用率高的服务,我们会进行多次部署,可能会部署在不同的服务器上,但是他们获取和操作的数据仍然是同一份。为了保证服务的强一致性,我们需要对线程进行加锁,但是因为我们部署在了不同的服务器上,而互斥锁只针对加锁的那台服务器,不会去限制别的服务器,所以是不能实现强一致性的要求的。(比如在8080的线程1获取完库存后,8081的线程1也进行了获取,此时8080的线程1对内存进行了扣除,按理来说已经没有库存了,但是8081的线程1获取的时候还是有的,还会继续扣除,这样就会出现问题)

这个时候我们就要使用分布式锁来解决问题了,分布式锁可以实现不同服务器上的监控,只要有一个线程获取了锁,其他的线程(包括其他服务器上的线程)都无法继续获取锁。

那么分布式锁怎么使用呢?通常我们使用redis的时候,会通过redis中的redission来实现分布式锁。

Redission:

redission实现分布式锁有三个重点:

watch dog:

我们知道,获取了锁之后如果不去释放锁,那么别的线程就都无法去使用相关的资源,那么如果加锁的线程因为某些原因终止了,没有去执行释放锁的命令怎么办呢?也许我们可以去设置锁的时间,到时间了就立马释放锁?这种方法理论可行,但是实际上每个线程需要花费的时间是无法确定的,如果时间少了加锁就没有意义,时间久了又占用资源。如果有一个旁观者,它可以告诉我们线程是否结束,如果结束了就释放锁,如果没结束就给锁加时就好了。watch dog就可以实现这个功能。

在某个线程加锁的同时,会生成一个新的线程来启动watch dog监控,如果加锁线程没有结束watch dog会每隔(releaseTime/3)的时间做一次续期(releaseTime默认30s),如果线程结束了,我们可以发送释放锁的指令来停止watch dog续期锁。

下面是redission的代码实现,这里有一个要注意的地方,如果我们在trylock的时候设置了锁自动释放时间,redission就会认为我们可以自己控制什么时候释放锁,就不会使用watch dog来帮助我们。

重试机制:

当有线程获取锁后,另外的线程会尝试循环获取锁,不过这个次数不是无限制的,存在一个阈值。

LUA脚本:

加锁、设置过期时间等操作都是基于lua脚本完成,可以保证代码的原子性。

除此之外,redission生成的分布式锁还有一些特点

可重录:

什么意思呢?就是在同一个线程中可以多次进行加锁(同一把锁),而每加一把锁,锁的value +1,每释放一把锁,锁的value -1。举个例子,在add1方法中,我们拿了一个“heimalock”锁,此时这个lock的记录如下

因为生成了锁,value为1,在add1方法中我们又调用了add2方法,add2方法同样也拿了一个“heimalock”锁,此时并不会创建新的锁,而是将value +1变成了2,此时这个lock的记录如下

释放锁其实就是value -1,不再过多赘述。

主从一致性:

redission不能实现,但是redission提供了redlock(红锁)来实现,只不过效率太低,如果要实现主从一致性,建议使用zookeeper

http://www.lryc.cn/news/382973.html

相关文章:

  • 【ARMv8/v9 GIC 系列 3 -- GIC 的 类型寄存器 GICD_TYPER】
  • MATLAB算法实战应用案例精讲-【数模应用】线性判别分析(附MATLAB、python和R语言代码实现)
  • 打造智能家居:用ESP32轻松实现无线控制与环境监测
  • 大型Web应用的模块化与组织实践:Flask Blueprints深入解析
  • AI 智算产业发展现状和预测报告
  • 【软件工具】Xshell安装教程
  • git如何切换到tag分支
  • 【启明智显产品介绍】Model3C工业级HMI芯片详解专题(三)通信接口
  • Mysql实战中的一些小tips
  • 【Linux】使用信号进行进程间通信
  • 电脑实用技巧1
  • 【D3.js in Action 3 精译】1.1.3 D3.js 的工作原理
  • 面试-java多线程与并发
  • 前端学习-day10
  • 深入理解桥接模式(Bridge Pattern)及其实际应用
  • Springboot + Mybatis 实现sql打印
  • Cesium默认bing地图数据,还支持哪些地图的数据源呢?
  • 高效、智能、安全:小型机房EasyCVR+AI视频综合监控解决方案
  • 数据分析的Excel基础操作
  • 【C语言】解决C语言报错:Invalid Pointer
  • 动态图形设计:创造视觉运动的艺术
  • CSS 属性 `mix-blend-mode`
  • 三大交易所全面恢复 IPO 申请
  • VC++开发积累——vc++6.0中删除函数的方法,右键,Delete
  • HBDNY-40/1端子排电压继电器 DC110V 导轨安装 约瑟JOSEF
  • Redis-数据类型-Geospatial(地理空间索引)
  • Python联动Mysql
  • vue3-openlayers 轨迹回放(历史轨迹)(ol-animation-path实现)
  • 计算机视觉全系列实战教程 (十二):图像分割(阈值分割threshold、分水岭算法watershed的使用步骤、洪水填充floodFill算法的使用)
  • Linux的免交互