redis redisson(仅供自己参考)

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

如图:

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

redisson可重入锁的原理

实现语言lua:

加锁实现脚本语言:

释放锁的脚本语言:

加锁的lua


-- 首先判断这个锁是否存在,也就是判断key是否存在。不存在则直接加锁,存在则判断是否flied是否存在,
if(redis.call('EXISTS',KEYS[1]) == 0)thenredis.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)thenredis.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,则释放锁,并减1if(redis.call('HEXISTS',KEYS[1],ARGV[1]) == 1) thenlocal num = redis.call('HGET',KEYS[1],ARGV[1]);local count = tonumber(num)if(count >1) thenredis.call('HINCRBY',KEYS[1],ARGV[1],-1)redis.call('EXPIRE',KEYS[1],ARGV[2])return 1elseredis.call('del',KEYS[1])return 1end
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.mzph.cn/diannao/45610.shtml

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

相关文章

复合索引abc,查询的时候查c a和ac都能用到索引吗

复合索引(也称为联合索引)的使用遵循“最左前缀原则”。这意味着查询条件必须从索引定义的最左边开始,并且连续地匹配索引中的列,才能有效地使用该索引。具体到你提到的复合索引 abc,它意味着索引按照 a、b 和 c 列的顺…

基于docker-compose部署zabbix7.0

1.安装docker和docker-compose 已有可跳过,没有参照我的docker一件安装脚本连接放在下方 一键安装dockerv24.0.6以及docker-compose可离线_docker 24对应docker-compose-CSDN博客 2.运行zabbix-server 1.创建zabbix工作目录 mkdir /zabbix 2.编写docker-compos…

求问DAMASK求解中关于yaml文件,报错显示:type dismatch in yaml date node

🏆本文收录于《CSDN问答解答》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&…

Transformer神经网络回归预测的MATLAB实现

Transformer神经网络最初是为自然语言处理(NLP)任务设计的,但它们也可以成功应用于其他序列数据的处理,如时间序列预测和回归任务。 在回归预测中使用Transformer网络通常涉及以下关键步骤和概念: 1. Transformer架…

代码随想录-暑假算法第一天(数组篇)

代码随想录-暑假算法第一天(数组篇) 1. 二分查找 力扣题目链接(opens new window) 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否…

DelayQueue实现延时任务

文章目录 DelayQueue基本概念Delayed接口示例内部实现原理应用场景小结 模拟超时订单处理Order 实体类OrderController 类OrderService 类OrderConsumer 类 DelayQueue DelayQueue是一个有序的阻塞队列,用于在指定的延迟之后从队列中提取元素。它在调度任务、缓存清…

回车不搜索直接页面刷新问题解决

使用技术栈:vue3、elementUiPlus 问题:回车触发方法,会刷新整个页面,不执行搜索 解决方法:在搜索的表单中增加submit.native.prevent submit.native.prevent

如何理解Java中的线程是如何运作的?

当你实现 Runnable 接口并重写 run 方法时,run 方法本身并不会被自动调用。Runnable 接口定义了一个没有参数的 run 方法,这个方法包含了你希望在线程中执行的代码。 要启动一个线程并执行 run 方法中的代码,需要做以下几步: 1.…

【HBZ分享】如何规避TCP的洪水攻击

常规洪水攻击的原理 在TCP第二次握手建立半连接时,此时就可以发动洪水攻击就是大量的请求发起TCP连接,当第二次握手时,服务器会把这些请求放到半连接队列中,由于这些恶意攻击的客户端不会再确认第三次握手,就导致这些…

接口幂等和防抖还在傻傻分不清楚。。。

最近想重温下接口幂等的相关知识,正所谓温故而知新,太久不CV的东西要是哪天CV起来都生疏了,哈哈哈 先从字面意思来温习下吧,幂等的官方概念来源于数学上幂等概念的衍生,如幂等函数,即使用相同的参数重复执…

GeoTrust ——适合企业使用的SSL证书!

GeoTrust是一家全球知名的数字证书颁发机构(CA),其提供的SSL证书非常适合企业使用。GeoTrust的SSL证书为企业带来了多重优势,不仅在验证级别、加密强度、兼容性、客户服务等方面表现出色,而且其高性价比和灵活的证书选…

arm操作系统的板子 怎么实现远程控制

安装适配arm操作系统的todesk 程序ToDesk远程桌面软件-免费安全流畅的远程连接电脑手机

C 语言中如何实现图结构?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会! 📙C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂,深入浅出,匠心打磨,死磕细节,6年迭代&…

PHP MySQL 简介

PHP MySQL 简介 PHP 和 MySQL 是现代网站开发中最流行的两种技术。PHP 是一种服务器端脚本语言,而 MySQL 是一种关系型数据库管理系统。这两种技术经常一起使用,以创建动态和交互式的网页。本文将简要介绍 PHP 和 MySQL 的基本概念、它们的工作原理以及…

[图解]分析模式-01-概述1

1 00:00:01,380 --> 00:00:01,770 好 2 00:00:02,340 --> 00:00:06,440 非常感谢大家能够来上我们 3 00:00:06,450 --> 00:00:07,960 分析模式高阶的课程 4 00:00:09,310 --> 00:00:13,440 这个内容之前在分析设计高阶 5 00:00:13,450 --> 00:00:17,840 也就…

C++ 指针变量做参数传递时的情况分析

前言 指针变量作为参数传递时,很容易混淆指针本身和指针指向的内容,实际应用中可能会导致无法预料的问题,所以做一下详细分析。 注意,在测试过程中为了看测试效果,有些指针变量分配了空间,但是未做回收&am…

电气常用知识

1、常开、常闭 在不加外力作用下,展示的状态就是常 因此,常开就是在不加外力作用下的 开的状态,也就是断开的状态 常闭就是在不加外力作用下的闭合的状态,也就是闭合的状态 2、单控双控 单控:一个东西只有两种状态…

Ubuntu 修改~/.bashrc终端选择是否使用annconda环境

首先需要明白的是anaconda虽然自带了python,但安装anaconda后并不会覆盖掉你原来的python(pip也是一样的),但安装anaconda后它会把自己的bin目录(里面有python、pip、conda等命令)加到PATH上,而…

Javassist 修改 jar 包里的 class 文件

前言 Javassist 是一个用于处理 Java 字节码的类库,可以用以修改 class 文件或 jar 包里的 class 文件。 简单来说我们用Java编写的代码是放在 java 格式的代码文件里,在编译的时候会编译为 class 格式的字节码文件,然后一般所有 class 文件…

GitHub每日最火火火项目(7.12)

项目名称:public - apis / public - apis 项目介绍:这是一个集体列表,包含了各种免费的 API。该项目可能致力于收集和整理不同领域的免费 API,为开发者提供便利,使其能够更轻松地获取所需的数据和功能。通过使用这些免…