专栏|分布式锁系列

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: reidsson

### Redisson


Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还实现了可重入锁(Reentrant Lock)、公平锁(Fair Lock、联锁(MultiLock)、 红锁(RedLock)、 读写锁(ReadWriteLock)等,还提供了许多分布式服务。


![Redisson](Redisson.jpg)


**特性功能**


- 支持 Redis 单节点(single)模式、哨兵(sentinel)模式、主从(Master/Slave)模式以及集群(Redis Cluster)模式

- 程序接口调用方式采用异步执行和异步流执行两种方式

- 数据序列化,Redisson 的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在 Redis 里的读取和存储

- 单个集合数据分片,在集群模式下,Redisson 为单个 Redis 集合类型提供了自动分片的功能

- 提供多种分布式对象,如:Object Bucket,Bitset,AtomicLong,Bloom Filter 和 HyperLogLog 等

- 提供丰富的分布式集合,如:Map,Multimap,Set,SortedSet,List,Deque,Queue 等

- 分布式锁和同步器的实现,可重入锁(Reentrant Lock),公平锁(Fair Lock),联锁(MultiLock),红锁(Red Lock),信号量(Semaphonre),可过期性信号锁(PermitExpirableSemaphore)等

- 提供先进的分布式服务,如分布式远程服务(Remote Service),分布式实时对象(Live Object)服务,分布式执行服务(Executor Service),分布式调度任务服务(Schedule Service)和分布式映射归纳服务(MapReduce)




**Watch dog**


![Redisson分布式锁](Redisson分布式锁.jpg)


总体的Redisson框架的分布式锁类型大致如下:


- **可重入锁**

- **公平锁**

- **联锁**

- **红锁**

- **读写锁**

- **信号量**

- **可过期信号量**

- **闭锁(/倒数闩)**




**实现方案**


添加依赖


```xml

<!-- 方式一:redisson-java -->

<dependency>

   <groupId>org.redisson</groupId>

   <artifactId>redisson</artifactId>

   <version>3.11.4</version>

</dependency>


<!-- 方式二:redisson-springboot -->

<dependency>

   <groupId>org.redisson</groupId>

   <artifactId>redisson-spring-boot-starter</artifactId>

   <version>3.11.4</version>

</dependency>

```


定义接口


```java

import org.redisson.api.RLock;

import java.util.concurrent.TimeUnit;


public interface DistributedLocker {


   RLock lock(String lockKey);


   RLock lock(String lockKey, int timeout);


   RLock lock(String lockKey, TimeUnit unit, int timeout);


   boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);


   void unlock(String lockKey);


   void unlock(RLock lock);

 

}

```


实现分布式锁


```java

import org.redisson.api.RLock;

import org.redisson.api.RedissonClient;


import java.util.concurrent.TimeUnit;


public class RedissonDistributedLocker implements DistributedLocker{


   private RedissonClient redissonClient;


   @Override

   public RLock lock(String lockKey) {

       RLock lock = redissonClient.getLock(lockKey);

       lock.lock();

       return lock;

   }


   @Override

   public RLock lock(String lockKey, int leaseTime) {

       RLock lock = redissonClient.getLock(lockKey);

       lock.lock(leaseTime, TimeUnit.SECONDS);

       return lock;

   }


   @Override

   public RLock lock(String lockKey, TimeUnit unit ,int timeout) {

       RLock lock = redissonClient.getLock(lockKey);

       lock.lock(timeout, unit);

       return lock;

   }


   @Override

   public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {

       RLock lock = redissonClient.getLock(lockKey);

       try {

           return lock.tryLock(waitTime, leaseTime, unit);

       } catch (InterruptedException e) {

           return false;

       }

   }


   @Override

   public void unlock(String lockKey) {

       RLock lock = redissonClient.getLock(lockKey);

       lock.unlock();

   }


   @Override

   public void unlock(RLock lock) {

       lock.unlock();

   }


   public void setRedissonClient(RedissonClient redissonClient) {

       this.redissonClient = redissonClient;

   }

 

}

```




**高可用的RedLock(红锁)原理**


RedLock算法思想是不能只在一个redis实例上创建锁,应该是在多个redis实例上创建锁,n / 2 + 1,必须在大多数redis节点上都成功创建锁,才能算这个整体的RedLock加锁成功,避免说仅仅在一个redis实例上加锁而带来的问题。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
安全 Java 关系型数据库
面试题30天打卡-day10
面试题30天打卡-day10
57 0
|
消息中间件 存储 NoSQL
面试题30天打卡-day23
面试题30天打卡-day23
38 0
|
8月前
|
存储 程序员 编译器
C++面试题其二
extern "C" 用于告诉编译器按照C语言的链接方式处理代码,通常用于C++代码与C代码混合编程,以防止因名字修饰(name mangling)引起的链接错误。例如: extern "C" { void c_function(); } 通过这些问题的深入理解和解答,能够更好地掌握C++编程的核心概念和实际应用,为面试做好充分的准备。
96 1
|
9月前
面试题
面试题
42 0
|
9月前
|
缓存 小程序 Java
【面试题】1、总结面试题1
【面试题】1、总结面试题1
70 0
|
9月前
|
JavaScript 前端开发
面试题总结
面试题总结
34 0
|
缓存 Dubbo Java
面试题30天打卡-day16
面试题30天打卡-day16
52 0
|
设计模式 负载均衡 Java
面试题30天打卡-day25
面试题30天打卡-day25
36 0
|
NoSQL 前端开发 Java
面试题30天打卡-day12
面试题30天打卡-day12
45 0
|
存储 缓存 NoSQL
面试题30天打卡-day19
面试题30天打卡-day19
43 0