基于数据库(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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎样备份电脑文件比较安全

域智盾软件是一款功能强大的电脑监控软件,它不仅具备实时屏幕监控、行为审计等功能,还能够对电脑文件进行备份和管理。下面将介绍域智盾软件如何备份电脑文件,以确保数据安全。 1、开启文档备份功能 部署后台,然后点击文档安全&a…

无需API实现MySQL与巨量引擎的对接

通过数环通,您可以使用不到几分钟的时间即可实现MySQL与巨量引擎的对接与集成,从而高效实现工作流程自动化,降本增效! 1.产品介绍 巨量引擎是字节跳动旗下的营销服务品牌,它整合了字节跳动旗下的产品及海量内容&#…

Diffusion Models CLIP

Introduction to Diffusion Models 生成模型 主要指的是无监督学习中的生成模型,在无监督学习中的主要任务是让机器学习给定的样本,然后生成一些新的东西出来。比如:给机器看一些图片,能够生成一些新的图片出来,给机器…

Jmeter进行压力测试不为人知的秘密

jmeter是apache公司基于java开发的一款开源压力测试工具,体积小,功能全,使用方便,是一个比较轻量级的测试工具,使用起来非常简单。因为jmeter是java开发的,所以运行的时候必须先要安装jdk才可以。jmeter是免…

窗口管理工具 Mosaic mac中文版功能特点

MosAIc mac是一种窗口管理工具,可帮助您在计算机屏幕上有效地组织和管理多个应用程序窗口。它提供了一种直观的方式来调整和排列窗口,以最大化工作效率。 MosAIc mac窗口管理软件功能和特点 窗口布局:MosAIc允许您选择不同的窗口布局&#x…

跟李沐学AI-深度学习课程00-03【预告、课程安排、深度学习介绍、安装】

目录 00 预告 01 课程安排 02 深度学习介绍 03 安装 本地安装 04 数据操作数据预处理 数据操作 数据类型 创建数组 访问元素 数据操作实现 入门 运算符 广播机制 索引和切片 节省内存 转换为其他Python对象 数据预处理实现 读取数据集 处理缺失值 转换为张…

【Linux】环境变量--PATH环境变量/环境变量的操作/命令行参数

文章目录 一、PATH环境变量1.什么是PATH环境变量2.如何添加PATH环境变量3.系统中的其他环境变量4.环境变量的来源 二、环境变量的操作1.设置环境变量2.通过getenv获取环境变量3.环境变量的意义 三、命令行参数 一、PATH环境变量 1.什么是PATH环境变量 这里我们先提出一个问题…

Ubuntu22.04离线安装uwsgi问题记录

GCC4.8安装 1、报错信息1: 由于缺少gcc4.8环境导致的无法安装uwsgi 解决方案: 离线安装GCC4.8环境, GCC4.8.5离线安装步骤如下: 1、下载gcc的离线安装包及其依赖包,链接如下: https://download.csdn.net/download/…

科技驱动固定资产管理变革:RFID技术的前沿应用

在当今激烈竞争的商业环境中,企业固定资产管理面临挑战,而RFID技术正以其独特特性和功能性彻底改变资产管理方式。本文将深入探讨RFID技术在固定资产管理中的革命性作用,并解析其应用带来的创新和便利。 RFID技术概述: RFID系统作…

君正X2100 读取CHIP_ID

每个处理器会有一个唯一的ID,这个ID可用做产品序列号,或其它。 X21000的CHIP_ID存放于芯片内部的efuse中,efuse是一次性可可编程存储器,初始值为全0,只能将0改为1,不能将1改为0。芯片出厂前会被写入一些信…

【开源】基于JAVA的智能停车场管理系统

项目编号: S 005 ,文末获取源码。 \color{red}{项目编号:S005,文末获取源码。} 项目编号:S005,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容A. 车主端功能B. 停车工作人员功能C. 系…

bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds: ceph-deploy mds

创建池 [rootceph-0 ~]# ceph osd pool create cephfs_data 64 pool cephfs_data created [rootceph-0 ~]# ceph osd pool create cephfs_metadata 32 pool cephfs_metadata created cephfs_metadata 64 报错 官方说明: 元数据池通常最多可容纳几 GB 的数据。为…

微软宣布计划在 Windows 10 版本 22H2 中引入 AI 助手 Copilot

根据之前的传言,微软宣布计划在 Windows 10 版本 22H2 中引入 AI 助手 Copilot。Copilot 将包含在 Windows 10 家庭版和专业版中。该更新的发布日期尚未公布,但预计将在不久的将来发布。 在一份新闻稿中,微软表示在向 Windows 11 用户提供 Co…

Netty传输object并解决粘包拆包问题

⭐️ 前言 大家好,笔者之前写过一篇文章,《Netty中粘包拆包问题解决探讨》,就Netty粘包拆包问题及其解决方案进行了探讨,本文算是这篇博客的延续。探讨netty传输object的问题。 本文将netty结合java序列化来传输object并解决粘包…

[PyTorch][chapter 63][强化学习-QLearning]

前言: 这里结合走迷宫的例子,重点学习一下QLearning迭代更新算法 0,1,2,3,4 是房间,之间绿色的是代表可以走过去。 5为出口 可以用下图表示 目录: 策略评估 策略改进 迭代算法 走迷宫实现Python 一 策略评估 强化学习最终是为了…

【网络奇遇记】那年我与计算机网络的初相识 —— 网络的体系结构

🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 一. 常见的三种计算机网络体系结构1.1 开放系统互连参考模型1.2 TCP/IP参考模型1.3 原理参考模型 二…

golang学习笔记——斐波纳契数列

斐波纳契数列 编写一个程序来计算某个数字的斐波纳契数列。 斐波那契数列是一个数字列表,其中每个数字是前两个斐波那契数字之和。 例如,数字 6 的序列是 1,1,2,3,5,8,数字 7 的序列是 1,1,2,3,5,8,13,数字 8 的序列是 1,1,2,3,5…

【机器学习7】优化算法

1 有监督学习的损失函数 1.1 分类问题 对二分类问题, Y{1,−1}, 我们希望sign f(xi,θ)yi, 最自然的损失函数是0-1损失, 函数定义特点0-1损失函数非凸、非光滑,很难直接对该函数进行优化Hinge损失函数当fy≥1时&…

leetcode刷题日记:141. Linked List Cycle(环形链表)

这一题是给我们一个链表让我们判断这是否是一个环形链表,我们知道如果一个链表中有环的话这一个链表是没有办法访问到尾的, 假若有如图所示的带环链表: 我们从图示中很容易看出来这一个链表在访问的时候会在里面转圈,我们再来看看…

群晖Docker(Container Manager)中安装Home Assistant Container

群晖Docker(Container Manager)中安装Home Assistant Container 不要使用 套件里面的 Home Assistant,不利于后期拓展 方式一: docker run -d --name"home-assistant-1" -v /volume1/docker/homeassistant/config:/c…