分布式锁的正确用法(第一节 ---基于单机的Redis)----Redisson

分布式锁:场景和使用方法(通俗讲解) 对于锁大家肯定不会陌生,比如 synchronized 关键字 和 ReentrantLock 可重入锁,一般我们用其在多线程环境中控制对资源的并发访问。但是随着业务的发展,分布式的概念逐渐出现在我们系统中,我们在开发的过程中经常需要进行多个系统之间的交互,于是上面的加锁方法就会失去作用。于是在分布式锁就自然而然的诞生了,接下来我们来聊一聊分布式锁实现的几种方式。 阅读详情

一般单机的情况我们用一个 Lock,synchronized锁锁住了就行了,为什么还要分布式锁呢,什么情况下会用分布式锁呢,带着问题,我们开始今天的精彩博弈---------------

什么时候用分布式锁?

诊所只有一个医生,很多患者前来就诊。

医生在同一时刻只能给一个患者提供就诊服务。

如果不是这样的话,就会出现医生在就诊肾亏的「肖菜鸡」准备开药时候患者切换成了脚臭的「谢霸哥」,这时候药就被谢霸哥取走了。

治肾亏的药被有脚臭的拿去了。

当并发去读写一个【共享资源】的时候,我们为了保证数据的正确,需要控制同一时刻只有一个线程访问。

分布式锁就是用来控制同一时刻,只有一个 JVM 进程中的一个线程可以访问被保护的资源。

分布式锁应该具备哪些特性?

1 互斥:在任何给定时刻,只有一个客户端可以持有锁;

2 无死锁:任何时刻都有可能获得锁,即使获取锁的客户端崩溃;

3 容错:只要大多数 Redis的节点都已经启动,客户端就可以获取和释放锁。

SETNX 命令是原子性的,那么为什么在分布式的时候不考虑它呢

带着场景去看看:
SETNX key value 命令是实现「互斥」特性。这个命令来自于SET if Not eXists的缩写,意思是:如果 key 不存在,则设置 value 给这个key,否则啥都不做。Redis 官方地址说的:

命令的返回值:

1:设置成功;
0:key 没有设置成功。

如下场景:

敲代码一天累了,想去放松按摩下肩颈。

168 号技师最抢手,大家喜欢点,所以并发量大,需要分布式锁控制。

同一时刻只允许一个「客户」预约 168 技师。

肖菜鸡申请 168 技师成功:

> SETNX lock:168 1
(integer) 1 # 获取 168 技师成功

谢霸哥后面到,申请失败:

> SETNX lock 2
(integer) 0 # 客户谢霸哥 2 获取失败

此刻,申请成功的客户就可以享受 168 技师的肩颈放松服务「共享资源」。

享受结束后,要及时释放锁,给后来者享受 168 技师的服务机会。

如何释放锁呢

> DEL lock:168
(integer) 1

在这里插入图片描述
肖菜鸡,事情可没这么简单。

这个方案存在一个存在造成锁无法释放的问题,造成该问题的场景如下:

客户端所在节点崩溃,无法正确释放锁;

业务逻辑异常,无法执行 DEL指令。

这样,这个锁就会一直占用,锁在我手里,我挂了,这样其他客户端再也拿不到这个锁了。

加超时释放锁----谁要这么写,就糟透了。

我可以在获取锁成功的时候设置一个「超时时间」比如设定按摩服务一次 60 分钟,那么在给这个 key 加锁的时候设置 60 分钟过期即可:

SETNX lock:168 1 // 获取锁
(integer) 1
EXPIRE lock:168 60 // 60s 自动删除
(integer) 1

这样,到点后锁自动释放,其他客户就可以继续享受 168 技师按摩服务了。
「加锁」、「设置超时」是两个命令,他们不是原子操作。
如果出现只执行了第一条,第二条没机会执行就会出现「超时时间」设置失败,依然出现锁无法释放。

setnx命令迭代升级

Redis 2.6.X 之后,官方拓展了 SET 命令的参数,满足了当 key 不存在则设置 value,同时设置超时时间的语义,并且满足原子性。

SET resource_name random_value NX PX 30000

NX:表示只有 resource_name 不存在的时候才能 SET 成功,从而保证只有一个客户端可以获得锁;
PX 30000:表示这个锁有一个 30 秒自动过期时间。

我们还要防止不能释放不是自己加的锁。我们可以在 value 上做文章。

把别人的锁拿去释放掉了

1 客户 1 获取锁成功并设置设置 30 秒超时;
2 客户 1 因为一些原因导致执行很慢(网络问题、发生 FullGC……),过了 30 秒依然没执行完,但是锁过期「自动释放了」;
3 客户 2 申请加锁成功;
4 客户 1 执行完成,执行 DEL 释放锁指令,这个时候就把客户 2 的锁给释放了。

--------》有个关键问题需要解决:自己的锁只能自己来释放。《------------

我要如何删除是自己加的锁呢?

我在加锁的时候设置一个「唯一标识」作为 value 代表加锁的客户端。
SET resource_name random_value NX PX 30000

在释放锁的时候,客户端将自己的「唯一标识」与锁上的「标识」比较是否相等,匹配上则删除,否则没有权利释放锁。

伪代码如下:

// 比对 value 与 唯一标识
if (redis.get("lock:168").equals(random_value)){
   redis.del("lock:168"); //比对成功则删除
 }

有没有想过,这是 GET + DEL 指令组合而成的,这里又会涉及到原子性问题
我们可以通过 Lua 脚本来实现,这样判断和删除的过程就是原子操作了。

// 获取锁的 value 与 ARGV[1] 是否匹配,匹配则执行 del
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

秒杀时候,下单扣减缓存也是这样操作的

 StringBuilder lua = new StringBuilder();
  lua.append("if (redis.call('exists', KEYS[1]) == 1) then");
  lua.append("    local stock = tonumber(redis.call('get', KEYS[1]));");
  lua.append("    if (stock == -1) then");
  lua.append("        return 1;");
  lua.append("    end;");
  lua.append("    if (stock > 0) then");
  lua.append("        redis.call('incrby', KEYS[1], -1);");
  lua.append("        return stock;");
  lua.append("    end;");
  lua.append("    return 0;");
  lua.append("end;");
  lua.append("return -1;");

这样通过唯一值设置成 value 标识加锁的客户端很重要,仅使用 DEL 是不安全的,因为一个客户端可能会删除另一个客户端的锁。

使用上面的脚本,每个锁都用一个随机字符串“签名”,只有当删除锁的客户端的“签名”与锁的 value 匹配的时候,才会删除它。

超时时间设置多长合适呢

这个时间不能瞎写,一般要根据在测试环境多次测试,然后压测多轮之后,比如计算出平均执行时间 200 ms。

那么锁的超时时间就放大为平均执行时间的 3~5 倍。
为啥要放放大呢?
因为如果锁的操作逻辑中有网络 IO 操作、JVM FullGC 等,线上的网络不会总一帆风顺,我们要给网络抖动留有缓冲时间。

加锁的时候设置一个过期时间,同时客户端开启一个「守护线程」,定时去检测这个锁的失效时间。

如果快要过期,但是业务逻辑还没执行完成,自动对这个锁进行续期,重新设置过期时间。
怎么实现上面这个业务呢,那就是我们今天的主角—Redisson
在使用分布式锁时,它就采用了「自动续期」的方案来避免锁过期,这个守护线程我们一般也把它叫做「看门狗」线程。

一路优化下来,方案似乎比较「严谨」了,抽象出对应的模型如下。

1 通过 SET lock_resource_name random_value NX PX expire_time,同时 启动守护线程为快要过期但还没执行完的客户端的锁续命;
2 客户端执行业务逻辑操作共享资源;
3 通过 Lua 脚本释放锁,先 get 判断锁是否是自己加的,再执行 DEL

加锁,锁的位置放哪里比较合适

根据前面的分析,我们已经有了一个「相对严谨」的分布式锁了。

于是「谢霸哥」就写了如下代码将分布式锁运用到项目中,以下是伪代码逻辑:


public void doSomething() {
  redisLock.lock(); // 上锁
    try {
        // 处理业务
        .....
        redisLock.unlock(); // 释放锁
    } catch (Exception e) {
        e.printStackTrace();
    }
}

有没有想过:一旦执行业务逻辑过程中抛出异常,程序就无法执行释放锁的流程。
所以释放锁的代码一定要放在 finally{} 块中。

加锁的位置也有问题,放在 try 外面的话,如果执行 redisLock.lock() 加锁异常,但是实际指令已经发送到服务端并执行,只是客户端读取响应超时,就会导致没有机会执行解锁的代码。
所以 redisLock.lock() 应该写在 try 代码块,这样保证一定会执行解锁逻辑。

public void doSomething() {
    try {
        // 上锁
        redisLock.lock();
        // 处理业务
        ...
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
      // 释放锁
      redisLock.unlock();
    }
}

可重入锁

Redisson 类库就是通过 Redis Hash 来实现可重入锁
当线程拥有锁之后,往后再遇到加锁方法,直接将加锁次数加 1,然后再执行方法逻辑。
退出加锁方法之后,加锁次数再减 1,当加锁次数为 0 时,锁才被真正的释放。
可以看到可重入锁最大特性就是计数,计算加锁的次数。
所以当可重入锁需要在分布式环境实现时,我们也就需要统计加锁次数。

加锁逻辑
我们可以使用 Redis hash 结构实现,key 表示被锁的共享资源, hash 结构的 fieldKey 的 value 则保存加锁的次数。
在这里插入图片描述
通过 Lua 脚本实现原子性,假设 KEYS1 = 「lock」, ARGV「1000,uuid」:

---- 1 代表 true
---- 0 代表 false
if (redis.call('exists', KEYS[1]) == 0) then
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return 1;
end ;
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return 1;
end ;
return 0;

加锁代码首先使用 Redis exists 命令判断当前 lock 这个锁是否存在。

如果锁不存在的话,直接使用 hincrby创建一个键为 lock hash 表,并且为 Hash 表中键为 uuid 初始化为 0,然后再次加 1,最后再设置过期时间。

如果当前锁存在,则使用 hexists判断当前 lock 对应的 hash 表中是否存在 uuid 这个键,如果存在,再次使用 hincrby 加 1,最后再次设置过期时间。

最后如果上述两个逻辑都不符合,直接返回。
解锁逻辑

-- 判断 hash set 可重入 key 的值是否等于 0
-- 如果为 0 代表 该可重入 key 不存在
if (redis.call('hexists', KEYS[1], ARGV[1]) == 0) then
    return nil;
end ;
-- 计算当前可重入次数
local counter = redis.call('hincrby', KEYS[1], ARGV[1], -1);
-- 小于等于 0 代表可以解锁
if (counter > 0) then
    return 0;
else
    redis.call('del', KEYS[1]);
    return 1;
end ;
return nil;

首先使用 hexists 判断 Redis Hash 表是否存给定的域。

如果 lock 对应 Hash 表不存在,或者 Hash 表不存在 uuid 这个 key,直接返回 nil。

若存在的情况下,代表当前锁被其持有,首先使用 hincrby使可重入次数减 1 ,然后判断计算之后可重入次数,若小于等于 0,则使用 del 删除这把锁。

解锁代码执行方式与加锁类似,只不过解锁的执行结果返回类型使用 Long。这里之所以没有跟加锁一样使用 Boolean ,这是因为解锁 lua 脚本中,三个返回值含义如下:

1 代表解锁成功,锁被释放
0 代表可重入次数被减 1
null 代表其他线程尝试解锁,解锁失败.

这一篇就到这里把,太长了阅读性不是很好,下一篇重点介绍Redisson

本文参考:
https://mp.weixin.qq.com/s?__biz=Mzg2MzU3Mjc3Ng==&mid=2247485064&idx=1&sn=06a9b0313707436f222a559a7e30d54e&chksm=ce77c0cff90049d975b93b6a37b9dc4bca9165872073b0ec273d1a8b02cfd4d06bc786c52c21&mpshare=1&scene=23&srcid=0820Pwg3JazA6bp0667cVWMB&sharer_sharetime=1661006754336&sharer_shareid=5e1f720976235b1e81fd0d6731dbec3a#rd

【并发编程】Redisson 的分布式锁 Redisson 是一个开源的用于操作 Redis 的 Java 框架。与 Jedis 和 Lettuce 等轻量级的 Redis 框架不同,它提供了更高级且功能丰富的 Redis 客户端。它提供了许多简化 Redis 操作的高级 API,并支持分布式对象、分布式锁、分布式集合等特性。Redisson 可以设置分布式锁的过期时间,从而避免锁一直被占用而导致的死锁问题。 阅读详情

相关推荐

Redis实现分布式锁

1. 为什么需要分布式锁?我们都知道,以上情况,,此时就2. 单机锁 & 分布式锁的定义:3. 分布式锁应该具备哪些条件?4. 分布式锁都有哪些主流的实现方案?分布式锁的核心是实现多线程之间互斥,而满足这一点的方式有很多,常见的有三种:补充:Zookeeper实现分布式锁的思路实现分布式锁的核心思路5. 如何用 Redis 实现分布式锁的?Redis本身可以被多个客户端访问,正好就是一个共享存储系统,可以用来保存分布式锁,而且Redis的读写性能高,可以应对高并发的锁操作场景。

weixin_53622554的博客 3284

redisson的分布式锁的使用

redisson的使用: 1、引入依赖 <!-- redisson 分布式锁--> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.15.3</version> </dep

码大师的博客 3711

springboot-redis-redisson分布式锁

springboot-redis-redisson分布式锁一、Redis分布式锁实现原理简介1.普通分布式锁2.哨兵模式3.集群模式唯一ID看门狗Watchdog可重入锁获取锁释放锁二、 完整代码依赖application.properties配置配置类锁后业务接口规范redis加锁接口规范redis加锁实现类自定义异常测试类 比较:redis很明显优于zookeeper;就分布式锁实现的健壮性而言,zookeeper很明显优于redis。如何选择,取决于你的业务! 一、Redis分布式锁实现原理 简介

没啥简介 2182

聊聊分布式锁——Redis和Redisson的方式

分布式~~锁,要这么念,首先得是『分布式』,然后才是『锁』分布式:这里的分布式指的是分布式系统,涉及到好多技术和理论,包括CAP 理论、分布式存储、分布式事务、分布式锁...分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。锁:对对,就是你想的那个,Javer 学的第一个锁应该就是Java 初级面试问题,来拼写下赛克瑞纳挨日的线程锁。

20年码农 4289

SHAP图全解析:从理论到实践,教你如何读懂和优化模型特征

本文全面解析SHAP图,从博弈论基础到实战应用,指导读者如何解读和利用SHAP值优化机器学习模型。通过详解特征重要性条形图、小提琴图、依赖图及决策图等关键可视化工具,帮助数据科学家精准诊断模型、识别特征交互,并将洞见转化为特征工程与模型调试的实际行动,有效提升模型可解释性与性能。

svm4gardener的博客 187

软件工程实验报告--用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图

用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图

m0_73814332的博客 4160

redis实战---分布式锁--单机篇

Redis分布式锁是一种基于Redis实现的分布式锁机制,它可以保证在分布式环境中,同一时刻只有一个客户端能够获取到锁,从而避免了多个客户端同时对同一资源进行修改的问题。接下来我将结合一个秒杀的例子讲述如果实现Redis的分布式锁。

郝老三~~~~~~~~~~~~~ 1131

使用 DEM 模拟金属烧结过程

了解离散元素法 (DEM) 如何彻底改变烧结工艺,提高制造业的效率和精度。

jkh920184196的博客 1125

Redis:Redisson分布式锁的使用(推荐使用)

通过这个命令,对客户端1的加锁次数,累加1。第一段if判断语句,就是用“exists myLock”命令判断一下,如果你要加锁的那个锁key不存在的话,你就进行加锁。会成立,因为myLock的hash数据结构中包含的那个ID,就是客户端1的那个ID,也就是“8743c9c0-0795-4907-87fd-6c719a6b4586:1”接着第二个if判断,判断一下,myLock锁key的hash数据结构中,是否包含客户端2的ID,但是明显不是的,因为那里包含的是客户端1的ID。

10JQKA的博客 2704

DRM驱动架构浅析-上(DRM基础概要与U-Boot阶段驱动解析)

本文主要探讨了Rockchip平台的DRM显示驱动架构及其在U-Boot阶段的实现。

一路寒风身如絮,命海沉浮客独行 1761

AD620仪表放大器模组实战:从调零到信号放大的完整指南

本文详细介绍了AD620仪表放大器模组的实战应用,从调零到信号放大的完整指南。AD620模组以其专业级性能和易用性成为微弱信号放大的首选,集成了AD620芯片、LM358运放和7660电源转换芯片。文章提供了调零技巧、增益设置方法以及单端与差分输入的正确连接方案,并通过心电信号采集和称重传感器等实际案例展示了其广泛应用。

weixin_29290379的博客 376

Redisson基于redis的分布式锁实现原理

在讲Redis之前,首先我们说一下啥是Redisson, 因为我们经常学的是Redis,但是在项目里面基本上都是用Redisson来使用Redis的能力。言归正传, Redisson是在Redis基础上实现的Java驻内存网格,它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。

qq_39201004的博客 1465

2023华为od机试真题【恢复数字序列】C++

2023华为od机试真题【恢复数字序列】C++ 对于一个连续正整数组成的序列,可以将其拼接成一个字符串,再将字符串里的部分字符打乱顺序。如序列8 9 10 11 12,拼接成的字符串为89101112,打乱一部分字符后得到90811211,原来的正整数10就被拆成了0和1。现给定一个按如上规则得到的打乱字符的字符串,请将其还原成连续正整数序列,并输出序列中最小的数字. 输入描述

MISAYAONE的博客 5729

Redisson 实现分布式锁

单机锁:用于一台服务器的同步执行。分布式锁:用于多台服务器之间的同步执行。有限资源的情况下,控制同一时间(段)只有某些线程(用户 / 服务器)能访问到资源。Java 实现锁:synchronized 关键字、并发包的类。Java synchronized 实现锁存在问题:只对单个 JVM 有效。分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。

weixin_69912448的博客 1635

把 SAP Activate 六个阶段看透:从项目落地到 SAP BTP 扩展与 AI 运营的一体化实践

摘要: SAP Activate 方法论常被误解为简单的项目阶段划分,实则是一套将业务目标、标准流程、系统配置和持续运营串联的实施控制体系。其六个阶段(Discover至Run)构成价值递进的实施通道,核心交付集中在Prepare到Deploy阶段。Discover阶段通过DDA评估确立项目方向与范围,Prepare阶段聚焦可执行性准备,Explore阶段采用Fit-to-Standard工作坊进行需求分层,Realize阶段基于前期决策进行配置与扩展开发。该方法论强调标准化优先,差异化需求通过SAP BT

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2329

YOLOv13改进策略【Neck篇】| GSConv 轻量卷积,Slim-Neck 减参数还不掉点

Neck 篇的第二篇继续"替换式"改进,这次的对象是 Neck 里的下采样卷积。GSConv 出自《Slim-neck by GSConv: a better design of lightweight detector》(2022),它的出发点:DWSConv(深度可分离)轻但"信息混不进通道",标准卷积重但表达好——GSConv 用GConv(分组卷积)混通道 + DWConv 补空间 + Channel Shuffle 打散,两全其美。

qq_53329130的博客 30

Redisson实现Redis分布式锁的N种姿势

点击蓝色“程序猿DD”关注我哟来源:阿飞的博客前几天发的一篇文章《Redlock:Redis分布式锁最牛逼的实现》,引起了一些同学的讨论,也有一些同学提出了一些疑问,这是...

程序猿DD 6566

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

基于Redis与Redisson实现分布式锁

分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在,单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为。而在如今的大型复杂系统中,通常采用的是分布式架构提供服务。分布式环境下,基于本地单机的锁无法控制分布式系统中分开部署客户端的并发行为,此时分布式锁就应运而生了。 一个可靠的分布式锁应该具有以下特征: ①互斥锁:作为锁,需要保证任何时候只能有一个客户端持有锁。 ②可重入:同一个客户端在获得锁后,可以再次进行加锁。 ③高可用:获取锁和释放锁的效率较高,不会出现单点故

猫咪老师 3228

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Redisson分布式锁

Redisson分布式锁

水w的博客 1990

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

分布式锁 redis redisson

通过uuid防止误删,但是还是存在问题,他不具备原子性的。如果在第一行代码执行后放行,突然间锁过时了或者发生其他事,导致锁被另外一个线程b得到了,那么第二行代码就删了那个线程b的锁。// 1. 从Redis中获取锁,set k1 v1 px 20000 nxRedisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。

2302_80490510的博客 1258

Redisson实现Redis分布式锁的N种姿势RedLock

前几天发的一篇文章《Redlock:Redis分布式锁最牛逼的实现》,引起了一些同学的讨论,也有一些同学提出了一些疑问,这是好事儿。本文在讲解如何使用Redisson实现Redis普通分布式锁,以及Redlock算法分布式锁的几种方式的同时,也附带解答这些同学的一些疑问。 Redis几种架构 Redis发展到现在,几种常见的部署架构有: 单机模式; 主从模式; 哨兵模式; 集群模式; ...

u010325193的博客 6590

Redis中的单机锁到分布式锁

Jedis 是 Redis 官方推荐的Java客户端开发包,后来SpringBoot对Redis客户端进行了封装使用了 redisTemplate,springBoot1.x底层使用的还是Jedis,而到了springBoot2.x时,具体实现变成了lettuce。今天我们从Redis的单机锁讲到分布式锁,分析了从Redlock到Lua脚本的演进,最后结合Spring的最佳实践,推荐了Redisson的使用。释放锁时,必须确保只有拥有锁的那个客户端才能释放它,否则可能会误释放别人的锁。

小蒋聊技术 1153

Redis中的分布式锁Redisson

Redis如何解决高并发场景带来的问题

qq_45993474的博客 1316

Redis分布式锁从入门到精通:从SETNX到Redisson看门狗机制

方案优点缺点适用场景SETNX基础版实现简单无续期、不可重入学习测试手动Lua脚本原子操作功能单一简单场景Redisson功能完善、自动续期、可重入引入依赖生产环境首选。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 1513

Redisson与Redis分布式锁

Redis分布式锁是一种在分布式系统中用于确保多个进程对共享资源互斥访问的机制。它通常通过Redis的原子指令来实现,比如使用SETNX(Set if Not eXists)指令来设置键,如果键不存在则操作成功,可以认为获取了锁;如果键已存在,则操作失败,表示锁被其他进程持有。但是,这种基本的实现可能会遇到各种问题,如锁无法自动释放导致的死锁问题,或者在高并发情况下的锁安全性问题。:使用SETNX指令来设置键,并使用EXPIRE指令为键设置一个过期时间,以避免死锁。:在SET指令中使用EX或PX。

qq_56438516的博客 1665

Redisson分布式锁实现及原理详解

客户端从N个 Redis 实例中请求锁,并设置相同的键、值和过期时间。客户端计算从每个 Redis 实例成功获取锁的时间。如果客户端能在大多数(即N/2 + 1个)Redis 实例中获取到锁,并且获取锁的总时间小于设定的超时时间,那么客户端成功获得了锁。如果客户端在大多数实例中获取了锁,客户端可以进行对共享资源的操作。如果锁超时后仍未成功获得足够多的实例锁,或者在操作过程中锁过期,则客户端应放弃该锁,等待下一次重试。操作完成后,客户端会向所有 Redis 实例发出解锁命令,以释放锁。

weixin_43287459的博客 2607
上一篇: 关于秒杀的细节,了解多少
下一篇: 分布式锁第二篇---Redisson的用法
凌晨里的无聊人
博客等级 码龄8年 2320粉丝 206原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值