基于数据库(MySQL)与缓存(Redis)实现分布式锁

分布式锁

分布式锁:分布式锁是在分布式的情况下实现互斥类型的一种锁
实现分布式锁需要满足的五个条件

  1. 可见性:多个进程都能看到结果
  2. 互斥性:只允许一个持有锁的对象的进入临界资源
  3. 可用性:无论何时都要保证锁服务的可用性(集群模式)
  4. 锁超时(死锁问题):允许持锁对象持锁最长时间,客户端一定可以获得锁
  5. 脑裂问题:集群同步时产生数据不一致,导致新的进程有可能拿到锁,但之前的进程以为自己还有锁,就出现了两个进程拿到了同一个锁的问题

基于数据库实现分布式锁

基于防重表(表记录)实现

  1. 创建锁表,内部存在字段表示资源名及资源描述,同一资源名使用数据库唯一性限制。
  2. 多个进程同时往数据库锁表中写入对某个资源的占有记录,当某个进程成功写入时则表示其获取锁成功。
  3. 其他进程由于资源字段唯一性限制插入失败陷入自旋并且失败重试。
  4. 当执行完业务后持有该锁的进程则删除该表内的记录,此时回到步骤一。

注意事项

  • 当某进程持有锁并且挂死时候会造成资源一直不释放,造成死锁,因为需要维护一个time字段,定时清理任务去清理持有过久的锁
  • 要设置为可重入模式,可以添加持有锁的进程的信息以及加锁的次数

基于悲观锁实现

  1. 关闭自动commmit属性
  2. 每次执行业务前使用查询语句后接for update锁定该行的数据
  3. 执行业务流程
  4. 提交commit

注意事项

  • 并发量很高的情况下,影响系统的可用性

基于乐观锁实现

表里面冗余一个版本号字段

  1. 每次执行业务前首先进行数据库查询,查询当前的需要修改的资源的版本号
  2. 进行资源的修改操作,但会比较一下当前数据的版本号与操作1中的版本号是否相同
  3. 如果相同修改资源,否则返回第一步

注意事项

  • 并发量很高的情况下,会对数据库造成很大的压力,同时并发不是很高
  • 对业务具有侵入性,设置版本号会增加数据库冗余

基于分布式缓存实现分布式锁

基于分布式缓存实现分布式锁,这个大多数都是依靠redis来进行实现的,所以我们也以redis来进行举例
使用set命令然后在这个命令后加一些参数来实现一个原子命令来设置对应过期时间或者使用lua脚本来实现这个功能
SET key value[EX seconds][PX milliseconds][NX|XX]
但是存在问题:

  • 锁过期了,但是业务还没有执行完
  • 锁被其他线程给误删了

避免被误删

对于value设置一个当前进程唯一的随机值
同时为了一个保证判断当前值是否一致以及删除键的操作是唯一的,那么就会使用到lua脚本

在Redis中,Lua脚本能够保证原子性的主要原因还是Redis采用了单线程执行模型。也就是说,当Redis执行Lua脚本时,Redis会把Lua脚本作为一个整体并把它当作一个任务加入到一个队列中,然后单线程按照队列的顺序依次执行这些任务,在执行过程中Lua脚本是不会被其他命令或请求打断,因此可以保证每个任务的执行都是原子性的。

锁续期机制

在redisson中有一个看门狗机制,相当于有一个后台线程,每隔10s都会检测一下,如果线程还持有锁,那么就会不断延长key的生存时间

RedLock

在企业里面大多数都是基于redis集群的状态,不会是单个节点,所以确保每个节点上都加上锁才是真正的加锁成功
RedLock:搞多个Redis master部署,以保证它们不会同时宕掉。并且这些master节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个master实例上,是与在Redis单实例,使用相同方法来获取和释放锁。
在这里插入图片描述

  1. 获取当前时间,以毫秒为单位
  2. 按顺序像五个节点请求加锁。客户端设置网络连接和响应超时时间,并且超时时间要小于锁的失效时间
  3. 用当前时间减去步骤1的时间,得到获取锁使用的时间,当且仅当超过一半的节点都获取到锁并且使用时间小于锁失效时间,锁才算获取成功
  4. 如果不满足步骤3则就是加锁失败,同时释放刚才的锁

实现锁重入

如果想实现可重入功能,那么可以使用redis里面的hash的数据结构,然后使用lua脚本来设置具体的值,具体要使用到的三个值就是下面的这三个命令
hset [name] [key] [value]
hincrby
expire

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/158942.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

刷题学习记录(攻防世界)

wife_wife 一拿到题目就提示这题不用爆破 进入环境得到的是一个登录框 随便试了一下登录账户密码会提示错误,那就去注册账户,注册的账户还有注册管理员的选项 先注册普通用户234,注册好后登录 这样就得到flag,但是提交是错误的&a…

智能井盖传感器能不能监测井盖位移

智能井盖传感器能够精准监测井盖的位移。这些传感器运用了前沿科技对井盖状态进行实时监测。一旦井盖出现异常移动传感器会立即捕捉到信号,并通过与互联网相连接的智能系统发出警报或记录数据。这种智能监测仪为城市或相关部门的井盖管理提供了实时数据支持&#xf…

Matlab通信仿真系列——信号处理函数

微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、Matlab信号产生函数…

Python网络编程多线程实现异步服务端

在《Python中通过socketserver库创建服务端》中提到的使用socketserver库创建的服务端是同步服务端。当有多个客户端接入服务端时,必须接收了客户端A发送的数据之后,才会再接收客户端B的服务端。而如果客户端A连接服务端后,没有发送数据&…

三菱FX3U小项目—运料小车自动化

目录 一、项目描述 二、IO口分配 三、项目流程图 四、项目程序 五、总结 一、项目描述 设备如下图所示,其中启动按钮SB1用来开启运料小车,停止按钮SB2用来手动停止运料小车(其工作方式任务模式要求)。当小车在原点SQ1位置,按下启动按钮S…

RocketMQ(三):集成SpringBoot

RocketMQ系列文章 RocketMQ(一):基本概念和环境搭建 RocketMQ(二):原生API快速入门 RocketMQ(三):集成SpringBoot 目录 一、搭建环境二、不同类型消息1、同步消息2、异步消息3、单向消息4、延迟消息5、顺序消息6、带tag消息7、带key消息 一…

关于python中内存分配的问题,运行一些操作可能会导致为新结果分配内存,用Python的id()函数演示

一、考虑背景: 一般在python中不会考虑像C中的内存问题,但是在一些高级应用中会考虑,例如有一个特别特别大的矩阵,最好不要不断的赋值,导致内存问题产生。 二、python中的id: 在python中有个id&#xff…

内网渗透之信息收集

目录 本机信息收集 查看系统配置信息 查看系统服务信息 查看系统登录信息 自动信息收集 域内信息收集 判断是否存在域 本机信息收集 查看系统配置信息 查看系统服务信息 查看系统登录信息 自动信息收集 域内信息收集 查看机器相关信息 查看用户相关信息 powershel…

【Java 进阶篇】深入浅出:JQuery 事件绑定的奇妙世界

在前端的世界里,事件是不可或缺的一部分。用户的点击、输入、滚动等行为都触发着各种事件,而如何在代码中捕捉并处理这些事件是每位前端开发者必须掌握的技能之一。本文将带你深入浅出,探索 JQuery 中的事件绑定,为你揭开这个奇妙…

ke11..--2其他界面也要提取我的locatStarage

获取浏览器里面的本地缓存 localStorage就是我们的浏览器缓存在哪都可以用 下面代码是获取打印到我们的页面上 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> …

【杂谈】-蓝牙低功耗数据传输模式比较

蓝牙低功耗数据传输模式比较 文章目录 蓝牙低功耗数据传输模式比较1、无连接数据传输2、无连接数据传输的优点3、无连接数据传输的局限性 3、面向连接的数据传输4、面向连接模式的优点5、面向连接模式的局限性6、家庭自动化项目的性能观察 物联网&#xff08;IoT&#xff09;设…

端口映射软件

今天给大家介绍一个自己制作的工具&#xff0c;本工具可以把本地自己的项目映射到外网可以访问,自己有域名可以使用自己的,没有可以用软件自带的三级域名! Token获取 地址&#xff1a;传送 打开上面网址注册账号&#xff0c;然后点击验证&#xff0c;复制里面的值即可。 软件…

报错:HikariPool-1 - Exception during pool initialization.

问题发现&#xff1a; 原本可以运行的springboot2项目突然无法运行且报错&#xff0c;HikariPool-1 - Exception during pool initialization。 问题分析&#xff1a; 观察报错信息发现是JDBC连接失败&#xff0c;进而搜索HikariPool-1&#xff0c;搜索得知应该是applicatio…

为什么鸿蒙调用弹窗组件(CommonDialog )却不展示或闪退?

鸿蒙OS开发问题 1.效果展示2.问题代码3.问题分析4.完整代码 1.效果展示 1.为什么调用弹窗不展示会闪退? 2.问题代码 1.前端代码: <?xml version"1.0" encoding"utf-8"?> <DirectionalLayoutxmlns:ohos"http://schemas.huawei.com/res/…

01线性回归

目录 常规求解&#xff1a; 矩阵求解 sklean算法求解 # 二元一次方程 # x y 14 # 2x - y 10 常规求解&#xff1a; x np.array([[1,1],[2,-1]])print(x) # [[ 1 1] # [ 2 -1]]y np.array([14, 10])w np.linalg.solve(x, y)print(正常求救&#xff1a;)print(w) …

契约锁助力货物进出口全程无纸化,加速通关、降低贸易成本

我国作为全球最大的制造业国家和最大的货物贸易国家&#xff0c;政府始终注重引入数字化技术&#xff0c;创新管理和服务模式&#xff0c;帮助降低企业进出口成本&#xff0c;加速货物流通。 近年国家海关总署、商务部、税务总局及各地政府在进出口“报关”、“提货”、“收货备…

Redis持久化策略之RDB与AOF

文章目录 1.RDB1)基本介绍2)自动触发3)手动触发4)RDB文件5)优点缺点 2.AOF1)基本介绍2)使用方式3)工作流程4)重写机制5)AOF文件6)优点缺点 3.RDB AOF 我们都知道&#xff0c;redis 是一个基于内存的数据库。基于内存的好处是访问速度快&#xff0c;缺点是“不持久”——当数据…

golang标准库-crc32的使用

1.概述 crc32实现了32位循环冗余检测算法的实现。目前crc32内部提供 了三种常用的多项式,采用查表法来提高计算checksum的效率。通过crc32.MakeTable()可以获取对应的表&#xff0c;crc32提供了一个IEETABLE可以直接使用&#xff0c;官方链接如下&#xff1a;crc32 package - h…

录屏软件无水印免费的有哪些?我来告诉你!

在日常生活和工作中&#xff0c;我们经常需要使用录屏软件来记录屏幕活动。然而&#xff0c;许多免费录屏软件在录制视频时会添加水印&#xff0c;给用户带来不便。那录屏软件无水印免费的都有哪些呢&#xff1f;在本文中&#xff0c;我们将介绍三款无水印的免费录屏软件&#…

如果面试也能这样说HashMap,那么就不会有那么多遗憾!

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…