Redis实现分布式锁有哪些方案?

news2024/11/17 22:42:58

Redis实现分布式锁有哪些方案?

在这里分享六种Redis分布式锁的正确使用方式,由易到难。

本文已收录到Java面试网站

方案一:SETNX+EXPIRE

方案二:SETNX+value值(系统时间+过期时间)

方案三:使用Lua脚本(包含SETNX+EXPIRE两条指令)

方案四::ET的扩展命令(SETEXPXNX)

方案五:开源框架~Redisson

方案六:多机实现的分布式锁Redlock

首先什么是分布式锁?

分布式锁是一种机制,用于确保在分布式系统中,多个节点在同一时刻只能有一个节点对共享资源进行操作。它是解决分布式环境下并发控制和数据一致性问题的关键技术之一。

分布式锁的特征:

1、「互斥性」:任意时刻,只有一个客户端能持有锁。

2、「锁超时释放」:持有锁超时,可以释放,防止不必要的资源浪费,也可以防止死锁。

3、「可重入性」“一个线程如果获取了锁之后,可以再次对其请求加锁。

4、「安全性」:锁只能被持有的客户端删除,不能被其他客户端删除

5、「高性能和高可用」:加锁和解锁需要开销尽可能低,同时也要保证高可用,避免分布式锁失效。

Redis分布式锁方案一:SETNX+EXPIRE

提到Redis的分布式锁,很多朋友可能就会想到setnx+expire命令。即先用setnx来抢锁,如果抢到之后,再用expire给锁设置一个过期时间,防止锁忘记了释放。SETNX是SETIF NOT EXISTS的简写。日常命令格式是SETNXkey value,如果 key不存在,则SETNX成功返回1,如果这个key已经存在了,则返回0。假设某电商网站的某商品做秒杀活动,key可以设置为key_resource_id,value设置任意值,伪代码如下:

img

缺陷:加锁与设置过期时间是非原子操作,如果加锁后未来得及设置过期时间系统异常等,会导致其他线程永远获取不到锁。

Redis分布式锁方案二:SETNX+value值(系统时间+过期时间)

为了解决方案一,「发生异常锁得不到释放的场景」,有小伙伴认为,可以把过期时间放到setnx的value值里面。如果加锁失败,再拿出value值校验一下即可。

这个方案的优点是,避免了expire 单独设置过期时间的操作,把「过期时间放到setnx的value值」里面来。解决了方案一发生异常,锁得不到释放的问题。

但是这个方案有别的缺点:过期时间是客户端自己生成的(System.currentTimeMillis()是当前系统的时间),必须要求分布式环境下,每个客户端的时间必须同步。如果锁过期的时候,并发多个客户端同时请求过来,都执行jedis.get()和set(),最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖。该锁没有保存持有者的唯一标识,可能坡别的客户端释放/解锁

分布式锁方案三:使用Lua脚本(包含SETNX+EXPIRE两条指令)

实际上,我们还可以使用Lua脚本来保证原子性(包含setnx和expire两条指令),lua脚本如下:

img

加锁代码如下:

img

Redis分布式锁方案四:SET的扩展命令(SET EX PX NX)

除了使用,使用Lua脚本,保证SETNX+EXPIRE两条指令的原子性,我们还可以巧用Redis的SET指令扩展参数。(SET key value[EX seconds]PX milliseconds][NX|XX]`),它也是原子性的

SET key value[EX seconds][PX milliseconds][NX|XX]

  1. NX:表示key不存在的时候,才能set成功,也即保证只有第一个客户端请求才能获得锁,而其他客户端请求只能等其释放锁, 才能获取。
  2. EXseconds:设定key的过期时间,时间单位是秒。
  3. PX milliseconds:设定key的过期时间,单位为毫秒。
  4. XX:仅当key存在时设置值。

伪代码如下:

img

Redis分布式锁方案五:Redisson框架

方案四还是可能存在「锁过期释放,业务没执行完」的问题。设想一下,是否可以给获得锁的线程,开启一个定时守护线程,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。当前开源框架Redisson解决了这个问题。一起来看下Redisson底层原理图:

img

只要线程一加锁成功,就会启动一个watchdog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了「锁过期释放,业务没执行完」问题。

分布式锁方案六:多机实现的分布式锁Redlock+Redisson

前面五种方案都是基于单机版的讨论,那么集群部署该怎么处理?

答案是多机实现的分布式锁Redlock+Redisson

最后分享一份我精心整理的大厂面试手册,包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等高频面试题,非常实用,有小伙伴靠着这份手册拿过字节offer~

需要的小伙伴可以自行下载

链接:http://mp.weixin.qq.com/s?__biz=Mzg2OTY1NzY0MQ==&mid=2247485445&idx=1&sn=1c6e224b9bb3da457f5ee03894493dbc&chksm=ce98f543f9ef7c55325e3bf336607a370935a6c78dbb68cf86e59f5d68f4c51d175365a189f8#rd

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

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

相关文章

谷粒商城实战(033 业务-秒杀功能4-高并发问题解决方案sentinel 2)

Java项目《谷粒商城》架构师级Java项目实战,对标阿里P6-P7,全网最强 总时长 104:45:00 共408P 此文章包含第332p-第p335的内容 熔断降级 开启对Feign远程服务的熔断保护机制 feign.sentinel.enabletrue 这里我们只是调用方加就行 被调用方不用加 正常…

【Ai】使用LabelStudio做数据标注

一、什么是LabelStudio LabelStudio是一个功能丰富、灵活便捷、易于使用的数据标注工具,适用于各种机器学习和深度学习项目中的数据标注工作。有特点如下: 多功能性:LabelStudio支持为多种数据类型创建自定义标注界面,包括图像、…

【会议征稿,五大海内外高校支持】第四届经济发展与商业文化国际学术会议(ICEDBC2024,6月21-23)

第四届经济发展与商业文化国际学术会议(ICEDBC2024)将于2024年6月21-23日在中国大连隆重召开。会议主要围绕“经济发展”“商业文化”等研究领域展开讨论。 旨在为经济,商业的专家学者及企业发展人提供一个分享研究成果、讨论存在的问题与挑战…

富瀚微FH8322 ISP图像调试—BLC校正

1、简单介绍 目录 1、简单介绍 2、调试方法 3、输出结果 富瀚微平台调试有一段时间了,一直没有总结,我们调试ISP的时候,首先一步时确定好sensor的黑电平值,黑电平如果不准,则会影响到后面的颜色及对比度相关模块。…

AI预测福彩3D采取888=3策略+和值012路或双胆下一测试6月11日新模型预测第1弹

很抱歉各位小伙伴,端午节三天去了趟外地,没有按时更新3D和排三的预测。前面跟大家说过,8码定位是关键,8码定位能稳定在80%的命中率,才有望通过缩号缩至200-250注以内通过等额方式进行投资。由于前面的模型对8码定位的效…

MONA来了 小鹏子品牌首车定名M03,20万内空间智能颜值都要能打

作者 |苗岭 编辑 |德新 小鹏汽车今日公布,MONA系列的第一款车正式命名为,小鹏M03。 9个月前,小鹏汽车从滴滴手中收购了代号为「达芬奇」的造车项目。 5月21日,何小鹏在小鹏汽车的第一季度财报会议上宣布,MONA系列的…

超详解——Python 编程中的类型和对象深入探讨——基础篇

目录 1. 内建类型的布尔值 1.1 布尔值的基本规则 1.2 进阶应用 2. 对象身份的比较 2.1 基本概念 2.2 示例代码 2.3 实际应用 3. 对象类型比较 3.1 基本概念 3.2 示例代码 3.3 实际应用 4. 类型工厂函数 4.1 常见的类型工厂函数 4.2 示例代码 4.3 实际应用 5. P…

【推荐收藏】2024年5款最佳 GPU 渲染引擎大盘点

2024年已经过半,对于从事3D渲染和数字内容创作的朋友来说,选择一款高效的GPU渲染引擎至关重要。今天,小编就来为大家盘点一下2024年5款最佳GPU渲染引擎。 1.V-Ray V-Ray是一款备受欢迎的3D GPU渲染引擎,被建筑、视觉特效、室内设…

阅读源码解析dynamic-datasource-spring-boot-starter中是如何动态切换数据源的

dynamic-datasource-spring-boot-starter是苞米豆提供的一个动态切换数据源的工具,可以帮助企业或者个人实现多数据源的切换,这里通过阅读源码的方式解析是如何动态的切换数据源的,采用的版本是3.5.1 源码解析 通过官方文档可以看到&#x…

leetcode 所有可能的路径(图的遍历:深度优先和广度优先)

leetcode 链接: 所有可能的路径 1 图的基本概念 1.1 有向图和无向图 左边是有向图,右边是无向图。对于无向图来说,图中的边没有方向,两个节点之间只可能存在一条边,比如 0 和 1 之间的边,因为是无向图&am…

抖音 根据sec uid获取个人详细信息(性别、年龄、属地、关注数、粉丝数、简介等)

本文带来用户的secuid获取用户信息以及其他基本信息: 话不多说看效果: 第一步输入用户sec_uid 根据secuid获取到用户基本信息: 可以支持接口批量转换,欢迎咨询

从数据采集到部署,手把手带你训练一个高质量的图像分类模型

本文来自社区投稿,作者李剑锋 MMPreTrain 是一款基于 PyTorch 的开源深度学习预训练工具箱,本文将从数据采集到部署,手把手带大家使用 MMPreTrain 算法库训练一个高质量的图像分类模型。 MMPreTrain 项目链接: https://github.co…

正则表达式(Linux 下搭配 grep 使用)

目录 1.基本正则表达式 2.扩展正则表达式 3.实操之grep筛选 3.1基本正则表达式 3.2扩展正则表达式 1.基本正则表达式 ^ 用于最左端,如^"abc",匹配以abc开头的行 $ 用于最右端,如"abc$",匹配以abc结尾的行 ^$ …

使用Oracle VM VirtualBox安装Centos7

下载软件 VirtualBox下载: https://www.virtualbox.org/ CentOS7下载:http://mirrors.aliyun.com/centos/7/isos/x86_64/(阿里云镜像下载快) VirtualBox下载好之后,双击运行后,根据提示直接下一步到底就行了。 下面开始安装cent…

接连获得2项认可!细探美创信创数据安全方案与实践

信创浪潮奔涌向前,筑信创防线,守数据安全,近年来,美创科技率先布局,持续在信创产品类型、产品更新迭代、国产信创改造服务、解决方案、生态建设等方面创新与实践,以满足各行业用户数据安全建设需求&#xf…

Redis为何如此快与其线程模型

Redis是单线程的为什么如此快 ①redis是基于内存的 首先,Redis 是基于内存的数据库,不论读写操作都是在内存上完成的,完全吊打磁盘数据库的速度。 ②Redis是单线程模型,从而避开了多线程中上下文频繁切换的操作 Redis 的单线程指的是 Red…

(2024,选择性遗忘,积极遗忘,消极遗忘)机器学习及其他领域的“遗忘”:综述

"Forgetting" in Machine Learning and Beyond: A Survey 公和众和号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0 摘要 1 引言 2 不同知识领域中的遗忘背景 2.1 心理学中的遗忘&…

responses-validator接口断言之状态码

概述 responses-validator 专用于对 reqeuests 的响应对象进行断言, 同时,为了更适用 yaml 的场景,支持了多种灵活、可扩展的写法,可用于搭建yaml接口自动化测试框架。 根据 reqeuests 响应对象的特点,responses-val…

电流监测利器!FP137宽共模范围高侧轨电流测量IC助您解决电流问题!

随着大量包含高精度放大器和精密匹配电阻的IC的推出,在高侧电流测量中使用差分放大器变得非常方便。高侧检测带动了电流检测IC的发展,降低了由分立器件带来的参数变化、器件数目太多等问题,集成电路方便了我们使用。本文将对FP137高端电流检测…

用Vue3构建一个交互式3D图

本文由ScriptEcho平台提供技术支持 项目地址:传送门 代码相关的技术博客 应用场景介绍 本代码段用于创建可用于展示服务或产品计划的卡片式组件。此类组件常见于网站或应用程序中,用于以清晰简洁的方式呈现不同级别的功能和定价信息。 代码基本功能…