解读分布式锁(redis实现方案)

news2024/9/26 5:21:57

1.导读

分布式锁是一种用于分布式系统中的并发控制机制,它用于确保在多个节点或多个进程之间的并发操作中,某些关键资源或代码块只能被一个节点或进程同时访问。分布式锁的目的是避免多个节点同时修改共享资源而导致的数据不一致或冲突的问题。通俗的来说,分布式锁的出现是为了解决分布式系统的问题,如果是单系统可以使用synchronized来完成资源的锁定,而如果是多系统环境,这个关键字只能控制本地的资源,由此诞生了分布式锁。

2.实现

初级版本1.1 

使用sentx对系统进行上锁,setnx是redis中提供的命令,主要作用是set一个key,但是区别set的操作是,nx代表的是not exit(不存在)即不存在才能set成功,存在会失败报nil。上锁之后就是正常的执行业务代码,执行完毕过后释放锁。而如果线程setnx失败的话,线程应该睡眠1s然后自旋,也就是重新递归调用自己,重复以上操作,睡眠是为了防止压力过大。具体setnx命令为set lock 123 NX,可以自己试试。

 

 升级版本1.2

思考:上面逻辑有什么问题?如果设置成功后,去执行代码,出现了异常或者业务闪断,是不是锁没有正常得到释放,这样B或者其他人都会一直无法使用,形成死锁,这个时候是不是就有聪明的人想到了使用过期时间expire。命令 

EXPIRE key seconds

 

 升级版版本1.3

同样上面设置同样会有问题,问题就出在设置过期时间这个环节可能也会出错,无法正常执行,这同上也会出现释放锁受阻,因此设置过期时间应该和setnx同属于原子操作,这样就算失败了也并没有设置上锁。具体操作是采用命令

set lock 123 Ex 30 NX

 

 升级版本2.1

关于删除lock释放锁的操作的问题

思考:如果你的业务时间非常长,A执行代码过程需要40s,但是你设置的过期时间是30s,然后B因为你的key过期,会马上获取到锁的资源,然后这个时候A又到了30s,会执行释放锁的操作,肯定会释放到B的线程的锁,释放了其他线程也会马上进入,就会造成多个线程在执行同一个锁的操作,完全没有实现锁的特性。

实现:考虑实现使用UUID去设置值,在释放锁的时候先去获取锁的值,如果能够匹配上UUID就执行删除锁的操作。

 

 升级版2.2

注意:if(get(lock) == UUID){del(lock)} 这段代码一般是由Java客户端在执行,这个时候就会出现非常致命的问题,get(lock)的过程中是Java端在像Redis过程中请求,假如你现在能够获取到lock的UUID,是属于A线程(本线程)的UUID的,但是在返回过程中,恰好又出现了过期时间过期了,这个时候B线程就会马上进入锁,执行后续操作!!!!问题来了,这个时候A以为自己还是成功获取到了,所以会删除lock,但是这个时候就会删除到B的lock,会出现上述现象。本质的产生就是释放锁(删除锁)的操作不是原子性的。

解决:lua脚本  官方的代码 KEYS[1] 就是lock 而 ARGV[1] 是UUID

if redis.call("get",KEYS[1]) == ARGV[1]
then
    return redis.call("del",KEYS[1])
else
    return 0
end

 这个本质你可以看成在redis内执行了获取key和删除的操作,所以并不存在Java客户端到Redis有往返造成的判断和删除非原子的情况。

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内网穿透技术 - 带你玩转NATAPP

前言 使用内网穿透工具,我们就可以在公网中直接访问在局域网内搭建的服务器网页,也可以直接远程连接到局域网内的机器。本文章主要介绍下NATAPP内网穿透工具的使用。 NATAPP使用教程 官网 在官网先注册,然后登录。登录后,会有一…

【弹力设计篇】弹力设计总结

前面主要聊了多个弹力设计,遮盖力主要做一个汇总 弹力设计总图 集群:服务不能是单点的,所以我们的架构需要冗余设计,设计成集群服务,也就是多个副本机制。需要具体的技术 负载均衡服务健康检查,使用像Ng…

飞桨AI Studio可以玩多模态了?MiniGPT4实战演练!

MiniGPT4是基于GPT3的改进版本,它的参数量比GPT3少了一个数量级,但是在多项自然语言处理任务上的表现却不逊于GPT3。项目作者以MiniGPT4-7B作为实战演练项目。 创作者:衍哲 一键fork fork该项目并运行,运行环境建议至少选择A100(4…

25.9 matlab里面的10中优化方法介绍—— 惩罚函数法求约束最优化问题(matlab程序)

1.简述 一、算法原理 1、问题引入 之前我们了解过的算法大部分都是无约束优化问题,其算法有:黄金分割法,牛顿法,拟牛顿法,共轭梯度法,单纯性法等。但在实际工程问题中,大多数优化问题都属于有约…

低代码PAAS平台源码,点击鼠标,就可以创建功能强大的企业应用程序,实现业务流程自动化

低代码PAAS平台采用对象方式实现字段、API的字段类型,引入RPA实现表自动化建模;再使用选择方式对地段功能进行选择定义甚至可以插入代码进行自定义。采用前后端同一技术,可实现功能应用边使用边修改的功能。 低代码PAAS平台,一套…

【100天精通python】Day15:python模块_第三方模块和包,模块如何以主程序形式执行

目录 1 常用的第三方模块 2. 第三方模块的安装和使用 2.1 安装第三方模块: 2.2 导入第三方模块: 2.3 使用第三方模块: 3 模块以主程序形式执行 4 python 中的包 4.1 python程序的包结构 4.2 创建包 4.3 python中包的导入和使用 5 …

redis 存储原理与数据模型

文章目录 一、redis的存储结构1.1 存储结构1.2 存储转换 二、字典(dict)实现2.1 数据结构2.2 哈希冲突2.3 扩容2.4 缩容2.5 渐进式rehash2.6 scan 命令2.7 expire机制 三、跳表(skiplist)实现3.1 理想跳表3.2 redis跳表 一、redis的存储结构 1.1 存储结构 1.2 存储转换 二、字…

Flowable-中间事件-信号中间抛出事件

定义 当流程执行到达信号抛出事件时,流程引擎会直接抛出信号,其他引用了与其相同的信号捕获 事件会被触发,信号发出后事件结束,流程沿后继路线继续执行。其抛出的信号可以被信号开始事 件(Signal Start Event&#xf…

vuejs源码阅读之优化器

前面讲过vuejs中解析器是把html模版解析成AST,而优化器的作用是在AST中找到静态子树并打上标记。 静态子树是指的那些在AST中永远不会发生变化的节点。 例如,一个纯文本节点就是静态子树,而带变量的文本节点就不是静态子树,因为…

VSCode配置之C++ SQLite3极简配置方案

背景 最近在学习《深入应用C11: 代码优化与工程级应用》,其中第13章说到SQLite库,查询网上诸多教程,发现比较容易出现bug且配置较为麻烦,故记录此次简化版方案,以供参考。 软件环境 SQLite 3.42.0 版本(仅…

基于Rsoft软件的达曼光栅仿真

1、概述 达曼光栅(Dammann grating,DG)是一种典型的二元光学元件(bianry optical elements,BOE),通过二元光学相位变化点的横向位置的调制来实现激光远场多级谱点等强度的光点阵列。 达曼光栅作为一种常用…

ReID网络:MGN网络(1) - 概述

Start MGN 1. 序言 现代基于感知的信息中,视觉信息占了80~85%。基于视觉信息的处理和分析被应用到诸如安防、电力、汽车等领域。 以安防市场为例,早在2017年,行业咨询公司IHS Market,我国在公共和私人领域安装有摄像头约1.76亿…

flask处理文件上传

flask处理文件上传 在Flask框架中,你可以使用request.files对象来处理文件上传。以下是一个简单的文件上传的示例: from flask import Flask, request from werkzeug.utils import secure_filename import osapp Flask(__name__)# 定义文件上传的路径…

二进制的妙用:判别2的幂次方的3把钥匙

本篇博客会讲解力扣“231. 2 的幂”的解题思路,这是题目链接。 这道题有3种巧妙的思路,且听我一一道来。 思路1 如果一个数是2的幂次方,则这个数的二进制中一定有且只有1位是1。比如,1的二进制是1,2的二进制是10&…

Python零基础入门(九)——函数,类和对象

系列文章目录 个人简介:机电专业在读研究生,CSDN内容合伙人,博主个人首页 Python入门专栏:《Python入门》欢迎阅读,一起进步!🌟🌟🌟 码字不易,如果觉得文章不…

Spring 6【方法参数校验、SpingAOP介绍、Schema-based方式实现AOP 】(十四)-全面详解(学习总结---从入门到深化)

目录 4.方法参数校验 SpingAOP介绍 Schema-based方式实现AOP 4.方法参数校验 Spring框架提供了一种校验方法参数的方法,在调用一个方法传入参数后,会判断参数是否满足数据校验。如果满足方法执行,如果不满足:不执行方法&…

Android跨进程传大图思考及实现——附上原理分析

1.抛一个问题 这一天,法海想锻炼小青的定力,由于Bitmap也是一个Parcelable类型的数据,法海想通过Intent给小青传个特别大的图片 intent.putExtra("myBitmap",fhBitmap)如果“法海”(Activity)使用Intent去传递一个大的Bitmap给“…

win10中CUDA cundnn pytorch环境搭建记录

关于在win10中安装cuda cudnn及pytorch全家桶(torch torchvision torchaudio)的详细安装步骤,可以参考这个帖子,说的非常详细! win10下pytorch-gpu安装以及CUDA详细安装过程 仅在此记录一下我的两台电脑安装的环境 目录 一、笔记本环境配置1.…

Leetcode-每日一题【剑指 Offer II 009. 乘积小于 K 的子数组】

题目 给定一个正整数数组 nums和整数 k ,请找出该数组内乘积小于 k 的连续的子数组的个数。 示例 1: 输入: nums [10,5,2,6], k 100输出: 8解释: 8 个乘积小于 100 的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], [2,6], [5,2,6]。 需要注意的是 [10,5,2]…

代码-【5 二叉树非递归后序遍历,找指定结点的父节点】

二叉树T按二叉链表存储,求指定结点q的父节点: