目录

1 基于Redis中setnx方法的分布式锁的问题

2 Redisson

2.1 什么是Redisson

2.2 Redisson实现分布式锁快速入门

2.3 Redisson 可重入锁原理

什么是可重入锁?

Redisson中又是如何实现的呢?

2.4 Redisson分布式锁的可重试性

2.5 Redisson分布式锁的主从一致性(MutiLock锁)


1 基于Redis中setnx方法的分布式锁的问题

之前我们使用setnx方法自定义的分布式锁,仍然会有许多的问题:

主要分为下面5点

1. 不可重入:即同一个线程无法多次获取同一把锁。

2. 不可重试:获取锁只尝试一次就返回false,没有重试机制

3. 超时释放:锁超时释放虽然可以避免死锁,但如果是业务执行耗时较长,也会导致锁释放,存在安全隐患

4. 主从一致性:如果Redis提供了主从集群,主从同步存在延迟,当主宕机时,如果从并同步主中的锁数据,则会出现锁实现。

这就需要我们去使用Redisson

2 Redisson

2.1 什么是Redisson

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。

说人话,它是一个基于Redis实现的分布式工具的集合,其中就包含了各种分布式锁的实现。

官网地址: https://redisson.org

GitHub地址: GitHub - redisson/redisson: Redisson - Redis Java client with features of In-Memory Data Grid. Over 50 Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Publish / Subscribe, Bloom filter, Spring Cache, Tomcat, Scheduler, JCache API, Hibernate, MyBatis, RPC, local cache ...

2.2 Redisson实现分布式锁快速入门

第一步,先引依赖。

 <!--Redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version></dependency>

第二步,配置Redisson客户端

@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient(){// 配置Config config = new Config();config.useSingleServer().setAddress("redis://192.168.150.101:6379").setPassword("123321");// 创建RedissonClient对象return Redisson.create(config);}
}

然后就可以使用Redisson中的getLock方法获取锁对象了。

在锁对象中通过tryLock方法尝试获取锁,该方法可以传入三个参数,分别是,获取锁失败的等待时间、超时时间和时间单位。默认分别是 -1秒(也就是不等待),30秒 和秒单位。

 //1.创建锁对象//SimpleRedisLock lock = new SimpleRedisLock(stringRedisTemplate, "order:" + userId);RLock lock = redissonClient.getLock("order:" + userId);//2.尝试获取锁boolean isLock = lock.tryLock();if (!isLock){//获取锁失败return Result.fail("一个用户只能下一单!");}try {IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId);} finally {//释放锁lock.unlock();}

2.3 Redisson 可重入锁原理

什么是可重入锁?

先看一段代码:

 方法1,先尝试获取锁,当获取锁成功后,调用方法2,在方法2中,又尝试获取锁,并执行完方法2的逻辑后,执行方法1 的逻辑,最后释放锁。

这个时候,因为方法1和方法2在同一个线程里,所以获取的是同一把锁,所以方法2中获取到的锁就是可重入锁。

Redisson中又是如何实现的呢?

很简单,就是新增了一个获取锁的次数。它舍弃了我们之前使用的Redis中String类型的setnx方法,改成用Hash类型的方法,分别存入锁的key,value存线程标识和锁的次数。

当同一个中的方法获取到同一把锁后,锁的次数+1,在释放锁的时候,不仅判断线程标识是否是自己的,还要判断锁的次数,如果次数-1 为0,采取释放锁。 以此来实现可重入锁。

我们可以根据此图来实现Lua脚本:

获取锁

释放锁:

2.4 Redisson分布式锁的可重试性

直接看底层实现原理:

这里主要三点:

1.当锁超时时间过期时,会使用看门口WatchDog不断重新设置超时时间去重试获取锁

2. 看门狗只有在我们没有设置超时时间,在超时时间默认的情况下才会有。

3.在每次重新获取锁之前,不会马上不断的进行去重试,会等待是否有释放锁的信号和不断的精确判断剩余超时时间是否充裕。

这样就能实现锁的重试了。

2.5 Redisson分布式锁的主从一致性(MutiLock锁)

主从一致性问题:

为了提高redis的可用性,我们会搭建集群或者主从,现在以主从为例

此时我们去写命令,写在主机上, 主机会将数据同步给从机,但是假设在主机还没有来得及把数据写入到从机去的时候,此时主机宕机,哨兵会发现主机宕机,并且选举一个slave变成master,而此时新的master中实际上并没有锁信息,此时锁信息就已经丢掉了。、

为了解决这个问题,redission提出来了MutiLock锁,使用这把锁咱们就不使用主从了,每个节点的地位都是一样的, 这把锁加锁的逻辑需要写入到每一个主丛节点上,只有所有的服务器都写入成功,此时才是加锁成功,假设现在某个节点挂了,那么他去获得锁的时候,只要有一个节点拿不到,都不能算是加锁成功,就保证了加锁的可靠性。

那么MutiLock 加锁原理是什么呢?笔者画了一幅图来说明

当我们去设置了多个锁时,redission会将多个锁添加到一个集合中,然后用while循环去不停去尝试拿锁,但是会有一个总共的加锁时间,这个时间是用需要加锁的个数 * 1500ms ,假设有3个锁,那么时间就是4500ms,假设在这4500ms内,所有的锁都加锁成功, 那么此时才算是加锁成功,如果在4500ms有线程加锁失败,则会再次去进行重试.

Redis实战——Redisson分布式锁相关推荐

  1. redis ,redisson 分布式锁深入剖析

    目录 为什么要用分布式锁? 分布式锁所遵循的原则? redis 分布式锁 redis 原始分布式锁实现 加锁 释放锁 redis 分布式锁存在的问题 redisson  实现分布式锁 redisson ...

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

    Redis:Redisson分布式锁的使用(生产环境下)(推荐使用) 关键词 基于NIO的Netty框架,生产环境使用分布式锁 redisson加锁:lua脚本加锁(其他客户端自旋) 自动延时机制:启 ...

  3. Redis进阶- Redisson分布式锁实现原理及源码解析

    文章目录 Pre 用法 Redisson分布式锁实现原理 Redisson分布式锁源码分析 redisson.getLock(lockKey) 的逻辑 redissonLock.lock()的逻辑 r ...

  4. 【Redis】Redisson 分布式锁主从一致性问题

    一.主从一致性问题的产生 Redis 主从集群使用如下: 在主节点进行数据的写操作: 在节点进行数据的读操作: 主节点向从节点同步数据. 主从一致性问题: 当主节点还没来得及将锁信息同步到从节点时,此 ...

  5. Redis进阶-细说分布式锁

    文章目录 Pre 引 分布式锁演进 V1 分布式锁演进 V2 分布式锁演进 V3 分布式锁演进 V4 分布式锁演进 V5 终极版-分布式锁演进(Redisson ) V6 Code Redisson分 ...

  6. Redisson分布式锁实现

    Redisson分布式锁实现 1. 分布式锁概述 2. 分布式锁实现 2.1 maven依赖 2.2 配置参数 2.3 代码实现 1. 分布式锁概述 程序中的锁就是为了解决临界资源访问的同步性问题,而 ...

  7. redisson分布式锁,实战

    目录 什么时候用分布式锁? 分布式锁入门 超时设置 释放了不是自己加的锁 正确设置锁超时 加解锁代码位置有讲究 实现可重入锁 Redis Hash 可重入锁 主从架构带来的问题 什么是 Redlock ...

  8. Redisson分布式锁轻松入门实战与讲解

    文章目录 一.Redisson 是什么? 二.整合 Redisson 2.1 引入 Maven 依赖 2.2 自定义配置类 2.3 测试配置类 三.分布式可重入锁 3.1 可重入锁测试 3.1.1 验 ...

  9. redis redisson 分布式锁 WRONGTYPE Operation against a key holding the wrong kind of value

    在使用redisson加锁的时候报错如下 trylock WRONGTYPE Operation against a key holding the wrong kind of value 错误场景: ...

最新文章

  1. 都说百度前端牛,来看看百度前端工程化之H5性能优化
  2. 基于张量分解和关系约束的多种类型的MicroRNA-疾病预测
  3. java注释的简单_Java简单注解
  4. 诺依曼原理中计算机由运算器,冯诺依曼原理与计算机的基本组成
  5. 前端 CSS Framework --- NEC (网易)
  6. CSS3中的border-radius兼容IE低版本解决方法
  7. 微服务升级_SpringCloud Alibaba工作笔记0025---Nacos持久化切换配置
  8. 【转】python编写规范——中标软件有限公司测试中心
  9. Wifi万能钥匙已经被淘汰了!Github这个开源工具太好用了!
  10. HTML5 简介与安装
  11. 独家可用发卡小程序源码下载卡密系统支持多种卡密领取模式流量主内附教程
  12. tplink迷你路由器中继模式_TP-Link TL-WR708N迷你无线路由器中继模式怎么设置
  13. rpi4b引导ubuntu分析------distro_bootcmd
  14. 地图瓦片坐标系定义及计算原理
  15. 统计数字liuseroj.picp.io
  16. 智能化工厂数字化管理系统软件解决方案
  17. OpenTCS打造移动机器人交通管制系统(五)
  18. 恶梦----------需求分析的漫延
  19. go语言negroni包介绍
  20. 20135203齐岳 信息安全系统设计基础期末总结

热门文章

  1. android imageview 多点触碰(MultiTouch)实现图片拖拽移动缩放
  2. 用HttpClient发送HTTPS请求报SSLException: Certificate for <域名> doesn’t match any of the subject alternativ
  3. 简单、好用的免费在线文字转语音软件
  4. PC 游戏修改常用工具
  5. Akka 学习(四)Remote Actor
  6. TLA+学习资料整理
  7. 网页英文 错位_css html网页错位原因解决方法
  8. word去掉页眉横线方法
  9. 通电自动高通900E是什么原理?
  10. 分享IT男人的健康饮食菜单