结论:
Lettuce连接被设计为线程安全的,所以一个连接所以被多个线程共同使用,也就是说在大多数情况下连接池不是必需的,他只有在某些特殊的场景下使用连接池才会带来比较大的正向收益,比如使用了Pipeline或者事务。
配置讲解
我们先看一张图:
图片.png配置
application.properties
spring.redis.host=host
spring.redis.database=0
spring.redis.password=pwd
spring.redis.port=port
# Connection timeout.
spring.redis.timeout=1000
# Maximum number of connections in the connection pool. A negative value indicates no limit.
spring.redis.lettuce.pool.max-active=50
# Minimum number of idle connections in the connection pool.
spring.redis.lettuce.pool.min-idle=5
# Maximum number of idle connections in the connection pool.
spring.redis.lettuce.pool.max-idle=50
# Maximum time for waiting for connections in the connection pool. A negative value indicates no limit.
spring.redis.lettuce.pool.max-wait=5000
# Interval for scheduling an eviction thread.
spring.redis.pool.time-between-eviction-runs-millis=2000
配置RedisConfiguration
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
lettuceConnectionFactory.setShareNativeConnection(true);
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(lettuceConnectionFactory);
// Use Jackson2JsonRedisSerializer to replace the default JdkSerializationRedisSerializer to serialize and deserialize the Redis value.
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(mapper);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// String serialization of keys
template.setKeySerializer(stringRedisSerializer);
// String serialization of hash keys
template.setHashKeySerializer(stringRedisSerializer);
// Jackson serialization of values
template.setValueSerializer(jackson2JsonRedisSerializer);
// Jackson serialization of hash values
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
把上面的原理图和配置文件我们对应起来看,我们能看到 lettuceConnectionFactory.setShareNativeConnection(true)这句代码,他代表的是多个线程操作的是同一个redis-client连接,也就是在redis-server这边可以看到只有一长连接(可以通过命令...查看到),这种就是图上的标注为“(a)”的线路逻辑。在我们平时通过非阻塞性的操作时(比如只是简单的get,set一个Key)这种多线程和单线程且单连接的性能差不太多。
现在我们把相关的代码改为false时: lettuceConnectionFactory.setShareNativeConnection(false),意味着会产生多个redis-client连接。有了多个本地redis-client连接大家普遍会认为这种性能会比单线程高,实际上他的性能大部分场景下比单个连接性能更低,大家可以去写代码去测试一下。所以这种场景一般是放在有很多阻塞性操作(事务,Pipeline)时才会使用。
具体详情可以看lettuce的官方对应章节:https://lettuce.io/core/5.3.1.RELEASE/reference/#connection-pooling.is-connection-pooling-necessary
网友评论