redis redisson(仅供自己参考)

news2024/9/20 17:10:02

redis 通过setnx实现的分布式锁有问题

如图:

解决的新的工具为(闪亮登场):redisson

redisson可重入锁的原理

实现语言lua:

加锁实现脚本语言:

释放锁的脚本语言:

加锁的lua


-- 首先判断这个锁是否存在,也就是判断key是否存在。不存在则直接加锁,存在则判断是否flied是否存在,
if(redis.call('EXISTS',KEYS[1]) == 0)then
    redis.call('HSET',KEYS[1],ARGV[1],'1')
    redis.call('EXPIRE',KEYS[1],ARGV[2])
    return 1
end
if(redis.call('HEXISTS',KEYS[1],ARGV[1]) == 1)then
    redis.call('HINCRBY',KEYS[1],ARGV[1],1)
    redis.call('EXPIRE',KEYS[1],ARGV[2])
    return 1;
end
return 0

释放锁的lua(比人觉得是在大于0的基础上减一,但是我觉得应该是在大于1的基础上减一。因为,在第一次加锁的时候,就设置为1,如果有其他重入则++,第二次则为2,删除顺序的话,应该是第一次大于1不删除,第二次释放锁等于1,也是最后一个锁,则直接删除了)


-- 删除逻辑,如果key存在,则查找flied,如果flied的值大于1,则释放锁,并减1

if(redis.call('HEXISTS',KEYS[1],ARGV[1]) == 1) then
    local num = redis.call('HGET',KEYS[1],ARGV[1]);
    local count = tonumber(num)
    if(count >1) then
        redis.call('HINCRBY',KEYS[1],ARGV[1],-1)
        redis.call('EXPIRE',KEYS[1],ARGV[2])
        return 1
    else
    redis.call('del',KEYS[1])
    return 1
    end
end
return 0

1、redisson的重入机制:通过redis hash实现

2、redisson的可重试机制:对于一个线程去获取锁,如果ttl(key的剩余过期时间),如果等于null,则为没有相对应的key,则可以加锁成功。如果不为null则说明已经key了,加锁失败。失败之后就是等待。等待也不是死等(一直while循环),因为redis在释放一个键的时候,会发布一个通知,其他线程一直等待这个通过,有了通知之后,再次判断是否已经过了等待时间(设置的一个线程最长的等待时间,如果超出则获取锁失败)。没有超过,则去获取锁,没有获取成功。判断是否超过设置的等待时间。如果没有超过则继续等待,这个等待就是在while循环当中(while循环里也不是一直循环,而是等待锁释放的通知)。

通知是发布订阅模式 :订阅:SUBSCRIBE mychannel(mychannel是订阅的频道) 发布:PUBLISH mychannel "Key deleted: mykey"(mychannel 是发布的频道)。发布和订阅是同一个频道,当有key删除,则redis发布这个频道的通知,其他线程收到这个通知之后,则就会去获取相应的锁了。

3、redisson超时释放:对于一个线程获取锁之后,key就会超时释放,这样就造成了并发的问题。为了解决这样的问题,给每一个获取锁的线程增加一个定时的任务(TimeOut),如果key释放的时间剩余key设置的释放时间的三分之一的话,就重新给key重新设置超时释放的值(这个值一直是原本的时间)。(看门狗机制)

4、主从节点:主节点(写,然后同步给从节点),用户的查询都到从节点(主查)。当主节点宕机,就会出现主节点的数据还没有同步到从节点,导致的一系列的问题。

        解决方法:使用集群节点,全部都是node,每个node都可以读写。避免了因为一个主节点宕机,从节点没有数据的情况。当是分布式锁的时候,只有当所有的节点的都加锁成功的时候,才会返回加锁成功,使用的redisson的mulit的联锁。

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

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

相关文章

Ubuntu安装MATLAB

一、准备工作 下载MATLAB安装文件: 访问MathWorks官方网站(MathWorks官网),下载适用于Linux的MATLAB安装文件。这通常是一个.iso镜像文件或.zip压缩文件。请注意选择与Ubuntu版本相匹配的MATLAB版本。创建安装目录: 打…

VMware安装Ubuntu以及利用vscode远程Ubuntu

一、VMware安装Ubuntu (1)VMware安装Ubuntu主要参考此文VMware虚拟机安装Ubuntu22.04图文教程(超详细!!!)。 (2)VMware密钥参考此文24年VMware 17密钥(附下载链接&#…

01. 数组篇(进行中......)

一. 前缀和技巧 &#xff08;1&#xff09;前缀和 前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。 class NumArray { public:vector<int> preSum; //前缀和数组NumArray(vector<int>& nums) {//preSum[0] 0&#xff0c;便于计算累加和preSum…

解决QT creator中文乱码问题

1.首先设置文本编辑器为UTF-8 先在工具-选项-文本编辑器-behavior部分选择文件编码为UTF-8&#xff0c;紧接着是选择“如果编码是UTF-8则添加”&#xff0c;如下图 2.设置ext code for tools 为system 具体解决办法是 工具-选项-环境-interfaces这一栏有一个“Text code for to…

【2024_CUMCM】Matlab快速入门

目录 常识 disp and input 字符串合并 sum 提取矩阵指定位置的元素 指定行列 指定行or指定列&#xff08;返回行/列向量&#xff09; 指定某些行 指定全部元素&#xff0c;按列拼接 size repmat 矩阵的运算 基本运算 形状相同的矩阵运算 每个元素同时和常数相乘或相…

揭秘!为何SmartEDA电路仿真成为学生的科技利器,学习之路从此不再难行

在当今科技日新月异的时代&#xff0c;电子工程、自动化、通信等专业的学生们面临着前所未有的学习挑战。传统的电路设计与分析方法已难以满足现代教学需求&#xff0c;而SmartEDA电路仿真软件的出现&#xff0c;如同为学生们带来了一盏明灯&#xff0c;照亮了他们的学习之路。…

C++-时间复杂度

前言 OJ测试中最烦人的结果莫过于TLE(Time Limit Exceed 超时)和MLE(Mempry Limit Exceed超内存&#xff09;了&#xff0c;在递归和搜索题里面看见这两货就烦。 目录 前言 时间复杂度 时间复杂度概念 时间复杂度的表示法 时间复杂度OJ测试要求 时间复杂度例举 剪枝 1.可行…

C++相关概念和易错语法(19)(继承规则、继承下的构造和析构、函数隐藏)

1.继承规则 继承的本质是复用&#xff0c;是结构上的继承而不是内容上的继承&#xff0c;近似于在子类中声明了父类的成员变量。 &#xff08;1&#xff09;写法&#xff1a;class student : public person 派生类&#xff08;子类&#xff09;&#xff0c;继承方式&…

Cypress UI自动化之安装环境

注&#xff1a;macOS系统 一、git环境 略 二、node环境 1、安装nvm 前提&#xff1a;有装过Homebrew&#xff0c;参考adb使用方法文档 1、安装nvm&#xff1a;首先要保证之前没有安装过node&#xff0c;如果之前安装过&#xff0c;先 brew uninstall node brew install n…

省市县下拉框的逻辑以及多表联查的实例

2024.7.12 一. 省市县的逻辑开发。1、准备&#xff1a;1.1. 要求&#xff1a;1.2 数据库表&#xff1a; 2. 逻辑&#xff1a;3. 方法3.1 创建实体类3.2 数据访问层3.3 实现递归方法3.4 控制器实现3.5 前端处理 二、多表联查&#xff08;给我干红温了&#xff09;1. 出现了问题2…

Java性能优化-switch性能优化-用String还是int做比较

场景 Java中使用JMH(Java Microbenchmark Harness 微基准测试框架)进行性能测试和优化&#xff1a; Java中使用JMH(Java Microbenchmark Harness 微基准测试框架)进行性能测试和优化_java热点函数-CSDN博客 参考以上性能测试工具的使用。 下面针对Java中对switch-case比较时…

LLM 合成数据生成完整指南

大型语言模型是强大的工具&#xff0c;不仅可以生成类似人类的文本&#xff0c;还可以创建高质量的合成数据。这种能力正在改变我们进行 AI 开发的方式&#xff0c;特别是在现实世界数据稀缺、昂贵或隐私敏感的情况下。在本综合指南中&#xff0c;我们将探索 LLM 驱动的合成数据…

访问控制的定义与原理

访问控制(Access Control)是一种重要的安全机制&#xff0c;用于限制对程序中的数据、函数、类以及计算机系统中资源(如文件、数据库、网络设备等)的访问权限。其主要目的是保护系统中的敏感信息和资源&#xff0c;防止未经授权的访问和操作&#xff0c;确保系统的安全性、完整…

无向图的双连通分量——AcWing 395. 冗余路径

无向图的双连通分量 定义 在无向图中&#xff0c;一个双连通分量&#xff08;Biconnected Component, BCC&#xff09;是指这样的子图&#xff1a;删除其中任意一个顶点都不会使这个子图分离成两个或更多个不相连的子图。换句话说&#xff0c;双连通分量是无割点的极大连通子…

lua 脚本语言 : 基础到高级语法

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

[Python学习篇] Python异常

什么是异常&#xff1f; 异常&#xff08;Exception&#xff09;是指在程序执行过程中发生的错误事件&#xff0c;它会中断程序的正常执行流程。异常可以由程序中的错误引发&#xff0c;也可以通过主动抛出异常来处理特殊情况。Python 使用异常处理机制来捕获和处理这些错误&am…

初识c++(构造函数,析构函数,拷贝构造函数,赋值运算符重载)

一、类的默认函数 默认成员函数就是用户没有显式实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。 #include<iostream> using namespace std; class Date { public:Date(){_year 1;_month 1;_day 1;cout << _year << "/" <&…

日常的学习

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Android ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 正文 7.11 resAndroidManifest 笔记 <> <> selector shape resources main下的AndroidMainifest.xml文件 application …

sql注入时间盲注

基于时间的盲注 也叫延时注入。通过观察页面&#xff0c;既没有回显数据库内容&#xff0c;又没有报错信息也没有布尔类型状态&#xff0c;那么我们可以考虑用“绝招”--延时注入。延时注入就是根据页面的响应时间来判断是否存在注入&#xff0c;一点一点注入出数据库的信息。我…

【进阶】利用python内置模块自动化发送邮件及邮件附件

目录 自动化发送邮件 流程&#xff1a; 步骤&#xff1a; 【重点】 【MIMEText--发送文本类型的邮件】 【MIMEImage-发送附件为图片的邮件】 【MIMEBase--发送附件为html报告的邮件】 自动化发送邮件 以qq邮箱为例&#xff0c;提前打开POP3/IMAP/SMTP/Exchange/CardDAV 服…