引言
分布式缓存是降低分布式应用程序延迟、提高并发性和可伸缩性的一种重要策略。redis 是一种流行的开源内存数据存储,可用作数据库、缓存或消息代理。由于是从内存而非磁盘加载数据,redis 比许多传统的数据库解决方案更快。redisson 是一个基于 redis 的框架,用 java 实现了一个 redis 包装器(wrapper)和接口,帮助我们将 redis 集成到 springboot 上。
依赖引入
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.15.5</version>
</dependency>
2022年7月26日 github 更新 3.17.5 版本为最新。
配置 redis
在 application.yml 文件添加 redis 的配置:
spring:
redis:
host: "127.0.0.1" #redis的地址
password: "123456" #默认没有密码
database: "1" #redis默认情况下有16个分片,这里配置具体使用的分片,不配置就是0
port: 6379 #默认端口6379
timeout: 3000 #连接超时时间(毫秒)
pool:
min-idle: 20
max-active: 30
读取配置可以使用 @Value 注解,例如读取 password:
@Value("${spring.redis.password}")
private String password;
也可以通过 @ConfigurationProperties 注解映射到配置类:
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "spring.redisson")//获取yml文件中以spring.redisson开头的配置
public class RedissonProperties {
private String address;
private String password;
private int database;
private int timeout;
}
初始化 RedissonClient
@Configuration
public class RedissonConfig {
@Value("redis://${spring.redis.host}:${spring.redis.port}")
private String address;
@Value("${spring.redis.database}")
private Integer database;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.pool.max-active}")
private int poolMaxActive;
@Value("${spring.redis.pool.min-idle}")
private int poolMinIdle;
@Bean
public RedissonClient redissonClient(){
Config config = new Config();
config.setCodec(JsonJacksonCodec.INSTANCE);
SingleServerConfig serverConfig = config.useSingleServer();
serverConfig.setAddress(address)
.setDatabase(database)
.setPassword(password)
.setTimeout(timeout)
.setConnectionPoolSize(poolMaxActive)
.setConnectionMinimumIdleSize(poolMinIdle);
return Redisson.create(config);
}
}
创建 cache
private static class DistributedLocalCacheImpl<K, V> implements DistributedLocalCache<K, V> {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private final RedissonClient redissonClient;
private final String cacheInstanceKey;
private final DistributedLocalCacheOption cacheOption;
private final Cache<K, Optional<V>> localCache;
private final Function<K, V> cacheLoader;
private final CacheEventBroadcaster cacheEventBroadcaster;
private final KeyCodec<K> keyCodec;
private final TypedJsonJacksonCodec valueCodec;
public DistributedLocalCacheImpl(RedissonClient redissonClient, String cacheInstanceKey,
DistributedLocalCacheOption cacheOption,
CacheEventBroadcaster cacheEventBroadcaster,
KeyCodec<K> keyCodec, TypeReference<V> valueTypeReference,
Function<K, V> cacheLoader) {
this.redissonClient = redissonClient;
this.cacheInstanceKey = cacheInstanceKey;
this.cacheOption = cacheOption.toBuilder().build();
this.localCache = CacheBuilder.newBuilder()
.initialCapacity(cacheOption.getInitCapacity())
.maximumSize(cacheOption.getMaxCapacity())
.expireAfterWrite(cacheOption.getTtl())
.expireAfterAccess(cacheOption.getMaxIdle())
.build();
this.cacheEventBroadcaster = cacheEventBroadcaster;
this.keyCodec = keyCodec;
this.valueCodec = new TypedJsonJacksonCodec(valueTypeReference, OBJECT_MAPPER);
this.cacheLoader = cacheLoader;
}
@Override
public synchronized <K, V> DistributedLocalCache<K, V> createCache(String cacheInstanceKey,
DistributedLocalCacheOption cacheOption,
KeyCodec<K> cacheKeyCodec,
TypeReference<V> valueTypeReference,
Function<K, V> cacheLoader) {
if (distributedLocalCacheMap.containsKey(cacheInstanceKey)) {
log.error("从分布式内存二级缓存加载数据异常");
}
DistributedLocalCacheImpl<K, V> cache = new DistributedLocalCacheImpl<>(
redissonClient, cacheInstanceKey, cacheOption, cacheEventBroadcaster,
cacheKeyCodec, valueTypeReference, cacheLoader
);
distributedLocalCacheMap.put(cacheInstanceKey, cache);
return cache;
}
在其他服务类中就可以调用 createCache 方法创建缓存。
总结
综上,redisson 提供了一种集成 redis 到 springboot 并实现分布式缓存的方法,能够简便地创建内存缓存,有助于降低分布式应用程序延迟、提高并发性和可伸缩性。