Недавно проект попытался обновить SpringBoot1.X до SpringBoot2.X, но клиентский драйвер Redis в Spring Boot 2.0 теперь изменился с Jedis на Lettuce, поэтому попробуйте протестировать использование Lettuce.Давайте кратко представим Lettuce.
Три основных клиента Redis
Введение
Jedis: это старый клиент реализации Java для Redis, который обеспечивает всестороннюю поддержку команд Redis.
Redisson: реализует распределенные и масштабируемые структуры данных Java.
Lettuce: высокоуровневый клиент Redis для потокобезопасного синхронного, асинхронного и реактивного использования, поддерживающий кластеры, Sentinel, конвейеры и кодировщики.
преимущество:
Jedis: предоставляет более полную операционную функцию Redis.
Redisson: способствовать разделению интересов пользователей по поводу Redis, предоставлять множество распределенных связанных операционных сервисов, таких как распределенные блокировки, распределенные коллекции, и поддерживать отложенные очереди через Redis.
Салат: в основном используется в некоторых структурах распределенного кэша.
регулируемый:
Джедаи: он использует блокирующий ввод-вывод, а вызовы его методов являются синхронными. Поток программы должен ждать, пока сокеты обработают ввод-вывод перед выполнением. Асинхронный режим не поддерживается.Экземпляры клиента Jedis не являются потокобезопасными, поэтому вам необходимо использовать Jedis через пул соединений..
Redisson: уровень связи, управляемый событиями, основанный на платформе Netty, вызовы методов которой являются асинхронными. API Redisson является потокобезопасным, поэтому одним соединением Redisson можно манипулировать для выполнения различных операций.
Lettuce: уровень связи, управляемый событиями, основанный на платформе Netty, вызовы методов которой являются асинхронными. API Lettuce является потокобезопасным, поэтому одним соединением Lettuce можно манипулировать для выполнения различных операций.
поддержка трубопровода
jedis могут поддерживать конвейер после определенного преобразования, вы можете увидеть подробностиКонвейер пакетных операций Redis
Но конвейерное поведение Lettuce странно.В случае метода executePipelined в Spring RedisTemplate:
有时完全是一条一条命令地发送
有时全合并几条命令发送
但跟完全 pipeline 的方式不同, 测试多次, 但没发现有一次是完整 pipeline 的
Поэтому, если вам нужно использовать конвейер, рекомендуется использовать Jedis.
Доступ к салату
единое видение
конфигурационный файл
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:4884,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, Object> source = new HashMap<>(8);
source.put("spring.redis.cluster.nodes", 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, 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;
}
}