当前位置: 首页 > news >正文

面试题:Redis 分布式锁存在什么问题 ?如何解决 ?

文章目录

  • 如何实现分布式锁
  • 2. Redis 分布式锁存在什么问题
    • 2.1 解决死锁问题
    • 2.2 解决锁误删问题


如何实现分布式锁

Redis 天生就可以作为一个分布式系统来使用,所以它实现的锁都是分布式锁。
图片

Redis 可以通过 setnx(set if not exists)命令实现分布式锁~

setnx mylock true - 加锁
del mylock - 释放锁
图片

通过执行结果是否为 1 可以判断是否成功获取到锁~

2. Redis 分布式锁存在什么问题

Redis 分布式锁存在两个问题:

死锁问题:未设置过期时间,锁忘记释放,加锁后还没来的及释放锁就宕机了都会导致死锁问题.

锁误删问题:设置了超时时间,但是线程执行超过超时时间后锁误删问题.

2.1 解决死锁问题

MySQL 中解决死锁问题是通过设置超时时间,Redis 也是如此,但是问题来了,第一步先加锁,然后再设置超时时间,那么就不满足原子性了,那么怎么办 ?

官方在 Redis 2.6.12 版本之后,新增了一个功能,我们可以使用一条命令既执行加锁操作,又设置超时时间:setnx 和 expire

图片

第一条命令成功加锁,并设置 30 s 过期时间

第二条命令跟在第一条命令后,还没有超过 30s,所以获取失败

2.2 解决锁误删问题

锁误删问题是解决死锁问题带来的问题,如何理解 ?

图片

既然知道了什么是锁误删问题,那么如何解决 ?

答:可以通过添加锁标识来解决.

前面我们使用 set 命令的时候,只使用到了 key,那么可以给 value 设置一个标识,表示当前锁归属于那个线程,例如 value=thread1,value=thread2…

但是这样解决依然存在问题,因为新增锁标识之后,线程在释放锁的时候,需要执行两步操作了:

  • 判断锁是否属于自己
  • 如果是,就删除锁

这样就不能保证原子性了,那该怎么办?

解决方案

使用 lua 脚本来解决 (Redis 本身就能保证 lua 脚本里面所有命令都是原子性操作)
使用 Redisson 框架来解决(主流)
那么 Redisson 如何实现分布式锁呢 ?

代码示例

1.引入 Redisson 依赖

<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.2</version>
</dependency>

2.创建 RedissonClient 对象

@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");// 如果有密码需要设置密码return Redisson.create(config);}
}

3.调用分布式锁

@RestController
public class LockController {@Resourceprivate RedissonClient redissonClient;@RequestMapping("/lock")public String lockResource() throws InterruptedException {String lockKey = "myLock";// 获取锁RLock lock = redissonClient.getLock(lockKey);try {// 超时时间 10s, [tryLock 获取成功才需要释放锁,获取失败不需要释放锁]boolean isLocked = lock.tryLock(20, TimeUnit.SECONDS);if(isLocked) {// 成功获取到锁try {TimeUnit.SECONDS.sleep(5);return "成功获取到锁,并执行业务代码";} catch (InterruptedException e) {e.printStackTrace();} finally {// 释放锁lock.unlock();}} else {// 获取锁失败return "获取锁失败";}} catch (InterruptedException e) {e.printStackTrace();}return "获取锁成功";}
}

启动项目,使用 8080 端口访问接口:

图片

相关文章:

面试题:Redis 分布式锁存在什么问题 ?如何解决 ?

文章目录 如何实现分布式锁2. Redis 分布式锁存在什么问题2.1 解决死锁问题2.2 解决锁误删问题 如何实现分布式锁 Redis 天生就可以作为一个分布式系统来使用&#xff0c;所以它实现的锁都是分布式锁。 Redis 可以通过 setnx&#xff08;set if not exists&#xff09;命令实…...

Container 命令ctr、crictl 命令

1、 Containerd和Docker的架构区别 Docker vs. Containerd&#xff1a; 2、ctr & crictl的区别 ctr是containerd的一个客户端工具 crictl 是 CRI 兼容的容器运行时命令行接口&#xff0c;可以使用它来检查和调试 Kubernetes 节点上的容器运行时和应用程序 crictl 则直接对…...

设计模式——七大原则

​更多内容&#xff0c;前往 IT-BLOG ​设计模式的目的是为了让程序&#xff0c;具有更好的代码重用性、可读性&#xff08;编程规范性&#xff0c;便于后期维护和理解&#xff09;、可扩展性&#xff08;当需要增加新需求时&#xff0c;非常方便&#xff09;、可靠性&#xf…...

笔记本电脑的WIFI模块,突然不显示了,网络也连接不上

问题复现&#xff1a; 早上&#xff0c;在更新完笔记本电脑的系统之后&#xff0c;连网之后&#xff0c;网络突然直接断开&#xff0c;一查看&#xff0c;WiFi模块居然不见了&#xff0c;开机重启也是如此&#xff0c;这种情况常常出现在更新系统之后&#xff0c;WiFi模块驱动就…...

Pytest 与allure测试报告集成

通过Feature, story, step 记录测试的功能&#xff0c;场景及测试步骤 # login.pylogin_func函数 传入参数是name 和 password 当输入的name和password与数据库db_data中数据一致时&#xff0c;返回“XXX成功登录系统&#xff01;” 当输入的name存在于数据库db_data但密码不正…...

MySQL 表的增删改查(基础)

1.CRUD 注释:在SQL中可以使用"--空格描述"来表示注释说明 CRUD 即增加(Create).查询(Retrieve).更新(Update).删除(Delete) 2.新增(Create) insert into 表名 values (列,列...); insert into 表名(列名,列名...) values (列,列...); insert into 表名 values(),(),…...

【PDF.js】发票PDF不显示文本的问题

控制台提示警告&#xff1a; Warning: loadFont - translateFont failed: "UnknownErrorException: The CMap "baseUrl" parameter must be specified, ensure that the "cMapUrl" and "cMapPacked" API parameters are provided.".…...

C#中检查空值的最佳实践

C#中检查空值的最佳实践 在C#编程中&#xff0c;处理空值是一项基础且重要的任务。正确地检查变量是否为null可以帮助我们避免NullReferenceException&#xff0c;这是C#最常见的运行时错误之一。本文将探讨为什么使用is关键字进行空值检查是一种优于使用的做法。 操作符&…...

三层交换组网实验(华为)

思科设备参考&#xff1a;三层交换组网实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 三层交换技术的出现&#xff0c;解决子网必须依赖路由器进行管理的问题&#xff0c;解决传统路由器低速、复杂所造成的网络瓶颈问题。一个具有三层交换功能的设备可简单理解为…...

Android配置GitLab CI/CD持续集成,Shell版本的gitlab-runner,FastLane执行,上传蒲公英

mac环境下&#xff0c; 首选需要安装gitlab-runner和fastlane brew install gitlab-runner brew install fastlane 安装完成&#xff0c;来到我们在gitlab下新建的Android项目&#xff0c;我们开始创建gitlab-runner 1、创建runner 点开runner&#xff0c;点击新建runner …...

算法提升——LeetCode383场周赛总结

周赛题目 边界上的蚂蚁 边界上有一只蚂蚁&#xff0c;它有时向左走&#xff0c;有时向右走。 给你一个非零整数数组nums。蚂蚁会按顺序读取nums中的元素&#xff0c;从第一个元素开始直到结束。每一步&#xff0c;蚂蚁会根据当前元素的值移动&#xff1a; 如果nums[i]<0…...

(delphi11最新学习资料) Object Pascal 学习笔记---第4章第2.1节( 带结果的Exit例程)

4.2.1 带结果的Exit例程 ​ 我们已经看到&#xff0c;从函数中返回结果所使用的语法与 C 语言家族的语法截然不同。不仅语法不同&#xff0c;行为也不同。为结果&#xff08;或函数名&#xff09;赋值并不像return语句那样终止函数。Object Pascal 开发人员经常利用这一特性&a…...

vuecli3 执行 npm run build 打包命令报错:TypeError: file.split is not a function

问题 今天有个项目在打包的时候遇到了一个问题&#xff0c;就是执行 npm run build 命令的时候报错了&#xff0c;如下&#xff1a; 解决 我排查了一下&#xff0c;模拟代码如下&#xff1a;在打包的时候用了 MinChunkSizePlugin const webpack require("webpack"…...

【Java 数据结构】对象的比较

Java中对象的比较 1. PriorityQueue中插入对象2. 元素的比较2.1 基本类型的比较2.2 对象比较的问题 3. 对象的比较3.1 覆写基类的equals3.2 基于Comparble接口类的比较3.3 基于比较器比较3.4 三种方式对比 4. 集合框架中PriorityQueue的比较方式5. 使用PriorityQueue创建大小堆…...

2024 Google Chrome 浏览器回退安装旧版本

2024 Google Chrome 浏览器回退安装旧版本 查看当前谷歌版本备份浏览器数据卸载浏览器双击重新安装旧版本浏览器 查看当前谷歌版本 详细参考&#xff1a;参考 笔记&#xff1a;最近谷歌浏览器更新后&#xff0c;用着总感觉别扭&#xff1a;不习惯 备份浏览器数据 &#xff…...

将数组中的各字符串都调整为指定长度调整原则:多删(删右侧多出的)少补(左侧补数字0)numpy.char.zfill()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将数组中的各字符串 都调整为指定长度 调整原则&#xff1a; 多删&#xff08;删右侧多出的&#xff09; 少补&#xff08;左侧补数字0&#xff09; numpy.char.zfill() [太阳]选择题 请问以…...

算法题目题单——图论

简介 本文为自己做的一部分图论题目&#xff0c;作为题单列出&#xff0c;持续更新。 题单由题目链接和题解两部分组成&#xff0c;题解部分提供简洁题意&#xff0c;代码仓库&#xff1a;Kaiser-Yang/OJProblems。 对于同一个一级标题下的题目&#xff0c;题目难度尽可能做…...

Maven提示Failure to find com.oracle:ojdbc14:jar:10.2.0.4.0

目录 问题 解决方案 1、下载oracle的驱动jar包 2、安装到本地仓库 3、检查本地仓库是否成功安装 4、Maven先clean &#xff0c;再install。 问题 项目引入Oracle依赖后报错&#xff0c;显示为红色。 解决方案 1、下载oracle的驱动jar包 首先我们要去下载一个oracle的…...

深度学习的数据集制作、标注、处理相关软件

制作深度学习数据集通常涉及数据的采集、标注和预处理等步骤。以下是一些可用于制作和处理深度学习数据集的软件工具&#xff0c;以及它们的详细介绍&#xff1a; 数据采集和生成 Web爬虫工具 (如 Scrapy, Beautiful Soup) 描述&#xff1a;这些工具可以帮助你从网上自动抓取和…...

点击按钮打开自定义iframe弹窗

1、效果 点击按钮打开弹窗&#xff1a; 打开弹窗后&#xff1a; 2、代码 <!DOCTYPE html> <html><head><title>iframe弹窗</title><style>/* 使用媒体查询来实现响应式设计 */media (min-width: 768px) {.popup {width: 80%; /* 设置…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

Python异步编程:深入理解协程的原理与实践指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 持续学习&#xff0c;不断…...

Electron简介(附电子书学习资料)

一、什么是Electron&#xff1f; Electron 是一个由 GitHub 开发的 开源框架&#xff0c;允许开发者使用 Web技术&#xff08;HTML、CSS、JavaScript&#xff09; 构建跨平台的桌面应用程序&#xff08;Windows、macOS、Linux&#xff09;。它将 Chromium浏览器内核 和 Node.j…...