Redisson简介
Redisson是架设在Redis基础上的一个Java驻内存数据网格。
数据网格是一种计算机架构,旨在将数据存储在内存中,并通过在内存中进行数据处理来提高性能和吞吐量。Java驻内存数据网格是指使用Java语言编写的数据网格,它在内存中存储和处理数据,可以有效地加速数据访问和处理。
Redisson是一个基于Java的开源的、高级的Redis客户端,它实现了Redis的分布式和响应式特性,Redisson能够让Java开发者更方便地与Redis进行交互。
简单来说Redisson就是一个Redis的客户端,RedisTemplate更高级,更简单。
Redisson常见作用
-
分布式对象:分布式对象简单来说就是存储在Redis中的Java对象。
Redisson允许你在分布式环境中创建Java对象,并将它们存储在Redis中。这样,不同的Java应用程序或服务就能够共享和访问这些对象,实现数据共享和数据同步。
-
分布式集合:简单来说就是将集合放在Redis中,并且可以多个客户端对集合进行操作。
Redisson支持常见的分布式数据结构,如List、Set、Map、Queue等,使得多个Java应用程序可以并发地访问和修改这些集合。
-
分布式锁:通过Redisson,你可以轻松地实现分布式锁,确保在分布式环境中的并发操作的正确性和一致性。
-
缓存:通过Redisson能够轻松的基于redis实现项目中的缓存
-
常见算法的分布式实现:Redisson提供了一些常用算法的分布式实现,如分布式信号量、分布式位图、分布式计数器等。
Redisson使用
导入依赖
SpringBoot需要导入对应的启动依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.1</version>
</dependency>
进行配置
Redisson的配置是在configuration类中进行配置的。
@Configuration
public class RedissonConfiguration {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
//设置redis的地址,这里是单机模式
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
//设置Redisson存储数据的格式,这里是使用的Json格式
config.setCodec(new JsonJacksonCodec());
return Redisson.create(config);
}
}
注入RedissonClient
在需要使用Redisson的地方注入RedissonClient就能正常使用了,下面我会列举一些使用场景。
@SpringBootTest
public class RedissonTest {
//注入RedissonClient
@Autowired
RedissonClient redissonClient;
@Test
public void test(){
//TODO 在这里可以通过RedissonClient进行操作
}
}
分布式对象案例
我们这里创建一个User类进行实验,User对象要实现序列化接口
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private Integer id;
private String username;
private String password;
}
然后我们使用Redisson提供的RBucket接口来操作对象,RBucket可以存储单个对象,对象类型是不限的。
PS:
Bucket的英文意思是:水桶。这里可以想象将一个Java对象放进水桶里面进行操作。
可以跟RedisTemplate中的ValueOperations进行比较理解。
ValueOperations<String, String> ops = redisTemplate.opsForValue();
新增
@Test
public void test(){
//创建一个User对象
User user = new User(1, "test", "password");
//获得一个RBucket实现类,参数是redis数据库中的key值
RBucket<User> bucket = redissonClient.getBucket("user:" + user.getId());
//执行set语句,将user对象存入redis中
bucket.set(user);
}
可以看到成功插入到redis数据库中
查询
@Test
public void get(){
//获得一个RBucket实现类,参数是redis数据库中的key值
RBucket<User> bucket = redissonClient.getBucket("user:1" );
User user = bucket.get();
System.out.println(user);
}
成功查询user对象
修改
修改依然是使用RBucket的set()
方法,也可以使用setIfExists()
方法
@Test
public void update(){
User user = new User(1, "newName", "newPassword");
RBucket<User> bucket = redissonClient.getBucket("user:" + user.getId());
//bucket.set(user); 不管key存在不存在都添加/修改值
bucket.setIfExists(user);
}
成功修改
删除
@Test
public void del(){
RBucket<User> bucket = redissonClient.getBucket("user:1" );
bucket.delete();
}
成功删除
分布式集合案例
当使用Redisson的分布式集合功能时,你可以在分布式环境中创建和操作各种类型的集合数据结构,如List、Set、Map等。这些集合数据结构会被存储在Redis中,并能够在不同的Java应用程序或服务之间共享和访问。下面我将分别给出List、Set的使用示例(Map同理)。
List
@Test
public void list(){
//在redis中创建一个key为testList的list
RList<String> list = redissonClient.getList("testList");
/*
注意:只要执行了add操作,就已经在redis中存入该数据了,并不需要另外的其他操作
*/
list.add("one");
list.add("two");
list.add("three");
}
@Test
public void list1(){
RList<String> list = redissonClient.getList("testList");
System.out.println(list);
}
执行这两个方法的结果是:能够顺利存入并且查询List
Set
@Test
public void set(){
RSet<Integer> set = redissonClient.getSet("testSet");
set.add(1);
set.add(2);
set.add(3);
set.add(1);//Set不允许重复元素,这个操作不会被执行
System.out.println("redis中testSet的值是:"+set);
}
测试结果
分布式锁案例
Redisson实现分布式锁是非常简单的,使用步骤就是:
-
通过RedissonClient获取RLock
-
然后使用RLock加锁
-
执行业务代码后,释放锁
@Test
public void lock(){
//会在redis中添加一个Map数据类型,Map的key是myLock
RLock lock = redissonClient.getLock("myLock");
try {
// 尝试加锁,等待时间为10秒,过期时间为30秒
boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
// 成功获取到锁,执行业务逻辑
System.out.println("获取锁成功,即将执行业务逻辑...");
Thread.sleep(30*1000);
} else {
// 加锁失败
System.out.println("获取锁失败,请稍后再试");
}
} catch (InterruptedException e) {
// 处理异常
} finally {
lock.unlock();
System.out.println("释放锁成功");
}
}
Redisson的优点就是实现分布式锁就像实现JVM锁一样,因为它继承了JUC的Lock接口
它底层帮我们实现了比较完善的分布式锁,适用于绝大多数场景,如果自己通过RedisTemplate实现分布式锁的话,会遇到相当多的问题,例如:全局锁失效、死锁、锁失效时间等问题,然而Redisson已经帮我们解决了。
缓存案例
Redisson依照Spring Cache标准提供了基于Redis的Spring缓存实现。 每个缓存(Cache)实例都提供了了两个重要的可配置参数:过期时间(ttl)和最长空闲时间(maxIdleTime),如果这两个参数都未指定或值为0,那么实例管理的数据将永久保存。
PS:
对SpringCache不熟悉的可以去看博主的另外一篇文章:Redis缓存和SpringCache
使用Redisson实现缓存的一般步骤为:
一、添加依赖
除了之前引入的Redisson的依赖,还添加SpringCache的依赖
<!--这里是SpringCache的启动依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.1</version>
</dependency>
二、启动类添加注解
在项目启动类添加@EnableCaching
注解
三、配置缓存管理器
在配置类中配置一个缓存管理器
@Configuration
public class RedissonConfiguration {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
config.setCodec(new JsonJacksonCodec());
return Redisson.create(config);
}
//这里是一个缓存管理器
@Bean
public CacheManager cacheManager(RedissonClient redissonClient){
/*
为Redisson的缓存管理器设置参数:
1.缓存数据12分钟过期。
2.最长空闲时间为10分钟。
*/
CacheConfig conf = new CacheConfig(12 * 60 * 1000, 10 * 60 * 1000);
HashMap<String, CacheConfig> map = new HashMap<>();
map.put("userCache",conf);
RedissonSpringCacheManager manager = new RedissonSpringCacheManager(redissonClient,map);
return manager;
}
}
四、使用缓存
这里是模拟通过id查询用户的Service方法。
通过@Cacheable
注解使方法启用缓存。
@Cacheable(value = "userCache",key = "#id",cacheManager = "cacheManager")
public User queryById(Integer id) {
return userMapper.selectById(id);
}