SpringBoot2.X整合Redis(單機+叢集+多資料來源)-Lettuce版
最近專案嘗試從SpringBoot1.X升級到SpringBoot2.X,但是 Spring Boot 2.0中 Redis 客戶端驅動現在由 Jedis變為了 Lettuce,所以嘗試測試一下Lettuce的使用. 下面簡單介紹一下Lettuce.
Redis 三大客戶端
簡介
Jedis:是Redis 老牌的Java實現客戶端,提供了比較全面的Redis命令的支援,
Redisson:實現了分散式和可擴充套件的Java資料結構。
Lettuce:高階Redis客戶端,用於執行緒安全同步,非同步和響應使用,支援叢集,Sentinel,管道和編碼器。
優點:
Jedis:比較全面的提供了Redis的操作特性
Redisson:促使使用者對Redis的關注分離,提供很多分散式相關操作服務,例如分散式鎖,分散式集合,可通過Redis支援延遲佇列
Lettuce:主要在一些分散式快取框架上使用比較多
可伸縮:
Jedis:使用阻塞的I/O,且其方法呼叫都是同步的,程式流需要等到sockets處理完I/O才能執行,不支援非同步。Jedis客戶端例項不是執行緒安全的,所以需要通過連線池來使用Jedis。
Redisson:基於Netty框架的事件驅動的通訊層,其方法呼叫是非同步的。Redisson的API是執行緒安全的,所以可以操作單個Redisson連線來完成各種操作
Lettuce:基於Netty框架的事件驅動的通訊層,其方法呼叫是非同步的。Lettuce的API是執行緒安全的,所以可以操作單個Lettuce連線來完成各種操作
pipeline 的支援
jedis 通過一定的改造後可以支援pipeline,具體可以看 Redis 批量操作之 pipeline
但是 Lettuce 的pipeline行為很奇怪. 在 Spring RedisTemplate 中的 executePipelined 方法中的情況:
有時完全是一條一條命令地傳送
有時全合併幾條命令傳送
但跟完全 pipeline 的方式不同,測試多次,但沒發現有一次是完整 pipeline 的
複製程式碼
所以如果需要使用pipeline的話,建議還是使用Jedis
Lettuce 接入
單機版
配置檔案
host: 192.168.131 .118
port: 4884
password: dsgs548
database: 0
# lettuce簡單配置
lettuce:
pool:
# 最大活躍連結數 預設8
max-active: 5
# 最大空閒連線數 預設8
max-idle: 10
# 最小空閒連線數 預設0
min-idle: 0
複製程式碼
redis配置類
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String,Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key採用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也採用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式採用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式採用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
複製程式碼
直接引入RedisTemplate 即可,單機版比較簡單
叢集版+多資料來源
配置檔案
spring:
redis:
cluster:
nodes: 192.168.131.118:4883,192.168.131.118:4884,192.168.131.118:4885
# nodes:
# - 192.168.131.118:4883
# - 1192.168.131.118:4884
# - 192.168.131.118:4885
password: adfafsas
lettuce:
pool:
# 最大活躍連結數 預設8
max-active: 5
# 最大空閒連線數 預設8
max-idle: 10
# 最小空閒連線數 預設0
min-idle: 0
secondaryRedis:
cluster:
nodes: 192.168.131.118:4883,192.168.131.118:4885
# nodes:
# - 192.168.131.118:4883
# - 192.168.131.118:4884
# - 192.168.131.118:4885
password: advfafasfsa
複製程式碼
redis配置類
@Configuration
public class RedisConfig {
@Autowired
private Environment environment;
/**
* 配置lettuce連線池
*
* @return
*/
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.redis.cluster.lettuce.pool")
public GenericObjectPoolConfig redisPool() {
return new GenericObjectPoolConfig();
}
/**
* 配置第一個資料來源的
*
* @return
*/
@Bean("redisClusterConfig")
@Primary
public RedisClusterConfiguration redisClusterConfig() {
Map<String,Object> source = new HashMap<>(8);
source.put("spring.redis.cluster.nodes",environment.getProperty("spring.redis.cluster.nodes"));
RedisClusterConfiguration redisClusterConfiguration;
redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration",source));
redisClusterConfiguration.setPassword(environment.getProperty("spring.redis.password"));
return redisClusterConfiguration;
}
/**
* 配置第一個資料來源的連線工廠
* 這裡注意:需要新增@Primary 指定bean的名稱,目的是為了建立兩個不同名稱的LettuceConnectionFactory
*
* @param redisPool
* @param redisClusterConfig
* @return
*/
@Bean("lettuceConnectionFactory")
@Primary
public LettuceConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig redisPool,@Qualifier("redisClusterConfig") RedisClusterConfiguration redisClusterConfig) {
LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build();
return new LettuceConnectionFactory(redisClusterConfig,clientConfiguration);
}
/**
* 配置第一個資料來源的RedisTemplate
* 注意:這裡指定使用名稱=factory 的 RedisConnectionFactory
* 並且標識第一個資料來源是預設資料來源 @Primary
*
* @param redisConnectionFactory
* @return
*/
@Bean("redisTemplate")
@Primary
public RedisTemplate redisTemplate(@Qualifier("lettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
return getRedisTemplate(redisConnectionFactory);
}
/**
* 配置第二個資料來源
*
* @return
*/
@Bean("secondaryRedisClusterConfig")
public RedisClusterConfiguration secondaryRedisConfig() {
Map<String,environment.getProperty("spring.secondaryRedis.cluster.nodes"));
RedisClusterConfiguration redisClusterConfiguration;
redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration",source));
redisClusterConfiguration.setPassword(environment.getProperty("spring.redis.password"));
return redisClusterConfiguration;
}
@Bean("secondaryLettuceConnectionFactory")
public LettuceConnectionFactory secondaryLettuceConnectionFactory(GenericObjectPoolConfig redisPool,@Qualifier("secondaryRedisClusterConfig")RedisClusterConfiguration secondaryRedisClusterConfig) {
LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build();
return new LettuceConnectionFactory(secondaryRedisClusterConfig,clientConfiguration);
}
/**
* 配置第一個資料來源的RedisTemplate
* 注意:這裡指定使用名稱=factory2 的 RedisConnectionFactory
*
* @param redisConnectionFactory
* @return
*/
@Bean("secondaryRedisTemplate")
public RedisTemplate secondaryRedisTemplate(@Qualifier("secondaryLettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
return getRedisTemplate(redisConnectionFactory);
}
private RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String,JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key採用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也採用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式採用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式採用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
複製程式碼