分布式锁框架-Redisson


基于Redis+看门狗机制的分布式锁框架

一、Redisson介绍

官网链接:https://redisson.org/

Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。

Redisson在基于NIO的Netty框架上,充分的利用了Redis键值数据库提供的一系列优势,在Java实用工具包中常用接口的基础上,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。

主要有以下几大特性:
云Redis管理、多样Redis配置支持、丰富连接方式、分布式对象、分布式集合、分布式锁、分布式服务、多种序列化方式、三方框架整合、完善工具等

  1. 支持云托管服务模式(同时支持亚马逊云的ElastiCache Redis和微软云的Azure Redis Cache):
  • 自动发现主节点变化
  1. 支持Redis集群模式(同时支持亚马逊云的ElastiCache Redis Cluster和微软云的Azure Redis Cache):
  • 自动发现主从节点
  • 自动更新状态和组态拓扑
  • 自动发现槽的变化
  1. 支持Redis哨兵模式:
  • 自动发现主、从和哨兵节点
  • 自动更新状态和组态拓扑
  1. 支持Redis主从模式
  2. 支持Redis单节模式
  3. 多节点模式均支持读写分离:从读主写,主读主写,主从混读主写
  4. 所有对象和接口均支持异步操作
  5. 自行管理的弹性异步连接池
  6. 所有操作线程安全
  7. 支持LUA脚本
  8. 提供分布式对象
    通用对象桶(Object Bucket)、二进制流(Binary Stream)、地理空间对象桶(Geospatial Bucket)、BitSet、原子整长形(AtomicLong)、原子双精度浮点数(AtomicDouble)、话题(订阅分发)、布隆过滤器(Bloom Filter)和基数估计算法(HyperLogLog)
  9. 提供分布式集合
    映射(Map)、多值映射(Multimap)、集(Set)、列表(List)、有序集(SortedSet)、计分排序集(ScoredSortedSet)、字典排序集(LexSortedSet)、列队(Queue)、双端队列(Deque)、阻塞队列(Blocking Queue)、有界阻塞列队(Bounded Blocking Queue)、阻塞双端列队(Blocking Deque)、阻塞公平列队(Blocking Fair Queue)、延迟列队(Delayed Queue)、优先队列(Priority Queue)和优先双端队列(Priority Deque)
  10. 提供分布式锁和同步器
    可重入锁(Reentrant Lock)、公平锁(Fair Lock)、联锁(MultiLock)、红锁(RedLock)、读写锁(ReadWriteLock)、信号量(Semaphore)、可过期性信号量(PermitExpirableSemaphore)和闭锁(CountDownLatch)
  11. 提供分布式服务
    分布式远程服务(Remote Service, RPC)、分布式实时对象(Live Object)服务、分布式执行服务(Executor Service)、分布式调度任务服务(Scheduler Service)和分布式映射归纳服务(MapReduce)
    13.支持Spring框架
  12. 提供Spring Cache集成
  13. 提供Hibernate Cache集成
  14. 提供JCache实现
  15. 提供Tomcat Session Manager
  16. 提供Spring Session集成
  17. 支持异步流方式执行操作
  18. 支持Redis管道操作(批量执行)
  19. 支持安卓(Andriod)系统
  20. 支持断线自动重连
  21. 支持命令发送失败自动重试
  22. 支持OSGi
  23. 支持采用多种方式自动序列化和反序列化(Jackson JSON,Avro,Smile,CBOR,MsgPack,Kryo,FST,LZ4,Snappy和JDK序列化)
  24. 超过1000个单元测试

二、在SpringBoot中使用Redisson

  • 添加依赖
<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson</artifactId>
   <version>3.21.3</version>
</dependency>
  • 配置yml
redisson:
	 addr:
		 singleAddr:
			 host: redis://127.0.0.1:6379
			 database: 0
  • 配置RedissonClient
@Configuration
public class RedissonConfig {

	 @Value("${redisson.addr.singleAddr.host}")
	 private String host;
	 
	 @Value("${redisson.addr.singleAddr.password}")
	 private String password;
	 
	 @Value("${redisson.addr.singleAddr.database}")
	 private int database;
	 
	 @Bean
	 public RedissonClient redissonClient() {
	 	Config config = new Config();
		config.useSingleServer().setAddress(host).setDatabase(database);
		return Redisson.create(config);
	 }
}

三、Redisson工作原理

在这里插入图片描述

四、Redisson使用扩展

4.1、Redisson单机连接

  • 配置yml
redisson:
	 addr:
		 singleAddr:
			 host: redis://127.0.0.1:6379
			 password: 12345678
			 database: 0
  • 配置RedissonClient
@Configuration
public class RedissonConfig {

	 @Value("${redisson.addr.singleAddr.host}")
	 private String host;
	 
	 @Value("${redisson.addr.singleAddr.password}")
	 private String password;
	 
	 @Value("${redisson.addr.singleAddr.database}")
	 private int database;
	 
	 @Bean
	 public RedissonClient redissonClient() {
	 	Config config = new Config();
		config.useSingleServer().setAddress(host).setPassword(password).setDatabase(database);
		return Redisson.create(config);
	 }
}

4.2、Redisson集群连接

  • 配置yml
redisson:
	 addr:
		 cluster:
			 hosts: redis://127.0.0.1:6379,...,redis://127.0.0.1:6388
			 password: 12345678
  • 配置RedissonClient
@Configuration
public class RedissonConfig {

	 @Value("${redisson.addr.cluster.hosts}")
	 private String hosts;
	 
	 @Value("${redisson.addr.cluster.password}")
	 private String password;
	 
	 /**
	 * 集群模式
	 * @return
	 */
	 @Bean
	 public RedissonClient redissonClient() {
	 	Config config = new Config();
	 	config.useClusterServers().addNodeAddress(hosts.split("[,]"))
			 .setPassword(password)
			 .setScanInterval(2000)
			 .setMasterConnectionPoolSize(10000)
			 .setSlaveConnectionPoolSize(10000);
	 	return Redisson.create(config);
	 }
}

4.3、Redisson主从连接

  • 配置yml
redisson:
	 addr:
		masterAndSlave:
			 masterhost: redis://127.0.0.1:6380
			 slavehosts: redis://127.0.0.1:6381,redis://127.0.0.1:6382
			 password: 12345678
			 database: 0
  • 配置RedissonClient
@Configuration
public class RedissonConfig {

	 @Value("${redisson.addr.masterAndSlave.masterhost}")
	 private String masterhost;
	 
	 @Value("${redisson.addr.masterAndSlave.slavehosts}")
	 private String slavehosts;
	 
	 @Value("${redisson.addr.masterAndSlave.password}")
	 private String password;
	 
	 @Value("${redisson.addr.masterAndSlave.database}")
	 private int database;
	 
	 /**
	 * 主从模式
	 * @return
	 */
	 @Bean
	 public RedissonClient redissonClient() {
		 Config config = new Config();
		 config.useMasterSlaveServers()
			 .setMasterAddress(masterhost)
			 .addSlaveAddress(slavehosts.split("[,]"))
			 .setPassword(password)
			 .setDatabase(database)
			 .setMasterConnectionPoolSize(10000)
			 .setSlaveConnectionPoolSize(10000);
		 return Redisson.create(config);
	 }
}

五、分布式锁总结

5.1、分布式锁特点

  1. 互斥性
    和我们本地锁⼀样互斥性是最基本,但是分布式锁需要保证在不同节点的不同线程的互斥。
  2. 可重入性
    同⼀个节点上的同⼀个线程如果获取了锁之后那么也可以再次获取这个锁。
  3. 锁超时
    和本地锁⼀样支持锁超时,加锁成功之后设置超时时间,以防止线程故障导致不释放锁,防止死锁。
  4. 高效,高可用
    加锁和解锁需要高效,同时也需要保证高可用防止分布式锁失效,可以增加降级。redission是基于redis的,redis的故障就会导致redission锁的故障,因此redission支持单节点redis、reids主从、reids集群
  5. 支持阻塞和非阻塞
    和 ReentrantLock ⼀样支持 lock 和 trylock 以及 tryLock(long timeOut)。

5.2、锁的分类

  1. 乐观锁与悲观锁
  • 乐观锁
  • 悲观锁
  1. 可重入锁和非可重入锁
  • 可重入锁:当在⼀个线程中第⼀次成功获取锁之后,在此线程中就可以再次获取
  • 非可重入锁
  1. 公平锁和非公平锁
  • 公平锁:按照线程的先后顺序获取锁
  • 非公平锁:多个线程随机获取锁
  1. 阻塞锁和非阻塞锁
  • 阻塞锁:不断尝试获取锁,直到获取到锁为止
  • 非阻塞锁:如果获取不到锁就放弃,但可以支持在⼀定时间段内的重试——在⼀段时间内如果没有获取到锁就放弃

5.3、Redission的使用

  1. 获取锁——公平锁和非公平锁
//获取公平锁
RLock lock = redissonClient.getFairLock("xxid");

//获取⾮公平锁
RLock lock = redissonClient.getLock("xxid");
  1. 加锁——阻塞锁和非阻塞锁
//阻塞锁(如果加锁成功之后,超时时间为30s;加锁成功开启看⻔狗,剩5s延⻓过期时间)
lock.lock();

//阻塞锁(如果加锁成功之后,设置⾃定义20s的超时时间)
lock.lock(20, TimeUnit.SECONDS);

//⾮阻塞锁(设置等待时间为3s;如果加锁成功默认超时间为30s)
boolean b = lock.tryLock(3, TimeUnit.SECONDS);

//⾮阻塞锁(设置等待时间为3s;如果加锁成功设置⾃定义超时间为20s)
boolean b = lock.tryLock(3, 20, TimeUnit.SECONDS);
  1. 释放锁
 lock.unlock();
  1. 应用示例
//公平⾮阻塞锁
RLock lock = redissonClient.getFairLock("xxid");
boolean b = lock.tryLock(3, 20, TimeUnit.SECONDS);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值