If both Lettuce
and Jedis
exist on the classpath, LettuceConnectionConfiguration
and JedisConnectionConfiguration
will be created, but actually JedisConnectionConfiguration
is not necessary. It is recommended to add redis client type configuration, for example:
spring.redis.client.type=jedis
,
spring.redis.client.type=lettuce
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
@ConditionalOnProperty(name = "spring.redis.client.type", havingValue = "jedis", matchIfMissing = true)
class JedisConnectionConfiguration extends RedisConnectionConfiguration {
//...
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisClient.class)
@ConditionalOnProperty(name = "spring.redis.client.type", havingValue = "lettuce", matchIfMissing = true)
class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
//...
}
Comment From: wilkinsona
If both Lettuce and Jedis are on the classpath, Lettuce should win. LettuceConnectionConfiguration
will define its redisConnectionFactory
bean and the equivalent bean in JedisConnectionConfiguration
should then back off as it is @ConditionalOnMissingBean(RedisConnectionFactory.class)
.
If you have both Lettuce and Jedis on the classpath, there's no easy way to use Jedis and a property could help with that (and would align with what we've done for JDBC datasources). I'm not sure what you mean by "JedisConnectionConfiguration
is invalid" though. Could you expand on that a bit please?
Comment From: brucelwl
@wilkinsona
1. If both Lettuce and Jedis are on the classpath, Lettuce should win. But now it seems that i can't specify the reids client type
2. if Lettuce win,JedisConnectionConfiguration
is not necessary to register in the spring container
Comment From: wilkinsona
if Lettuce win,JedisConnectionConfiguration is not necessary to register in the spring container
This could be addressed by moving the @ConditionalOnMissingBean(RedisConnectionFactory.class)
from the @Bean
method to the class.
If both Lettuce and Jedis are on the classpath, Lettuce should win. But now it seems that i can't specify the reids client type
Thanks. I understand what you're suggesting now.
Comment From: onobc
@wilkinsona I was going to head out on this unless you plan on doing so.
My intention is to add the client type property and use that to choose the connection factory as suggested above. That also brings up a question for RedisProperties
. There is a clientName
property currently. Should we add another clientType
or go ahead and split into its own property object -> client.name
client.type
. ?
Comment From: snicoll
I am having second though about this one. As far as I remember, Jedis in in maintenance mode and Lettuce is the recommended choice. There are a number of things the user could do for this particular problem:
- If Jedis is brought by a dependency, they can fine tune their build to exclude the unwanted dependency
- They can exclude the Lettuce auto-configuration
I know we've considered dropping support for Jedis at some point. If that's still the target, I don't think exposing a property for it makes sense.
Paging @mp911de for more feedback.
Comment From: onobc
In light of that info about Jedis, it does not seem like more effort should be added in this area.
they can fine tune their build to exclude the unwanted dependency
One technique that has worked for me is to leverage Gradle capabilities to force users to choose between a set of "mutually exclusive" dependencies.
Comment From: snicoll
@brucelwl can you please expand a bit on your use case? Why do you have both lettuce and jedis on the classpath? If you prefer Jedis, wouldn't it be better to exclude lettuce?
Comment From: brucelwl
@brucelwl can you please expand a bit on your use case? Why do you have both lettuce and jedis on the classpath? If you prefer Jedis, wouldn't it be better to exclude lettuce?
If the whole project is developed by the team itself, we can select only one client type. However, sometimes we use toolkits developed by other teams. If they use lettuce
and we use jedis
, and we usejedis native client
instead of RedisTemplate
, For us, switching from jedis to lettuce is not a simple dependency change. It may involve changes in the underlying code implementation. However, we may not be able to take a greater risk and hope that the two clients will coexist
Comment From: snicoll
It looks like you’d like Spring Boot to configure both lettuce and Jedis in your app. Is this correct?
Comment From: brucelwl
It looks like you’d like Spring Boot to configure both lettuce and Jedis in your app. Is this correct?
I hope springboot auto configure
can support specifying redis client types when both Jedis and Lettuce are on the classpath
Just like spring boot, it supports specifying the DataSource
type.
At present, we do have both Lettuce
and Jedis
in our project, but at this time, we can't choose jedis
as the underlying dependency of RedisTemplate
or RedisConnectionFactory
Comment From: snicoll
I have to assume the answer to my question is no. If you can’t exclude lettuce from the classpath and you want to configure jedis, you could exclude LettuceAutoConfiguration. Can you please try that?
Comment From: brucelwl
I have to assume the answer to my question is no. If you can’t exclude lettuce from the classpath and you want to configure jedis, you could exclude LettuceAutoConfiguration. Can you please try that?
This solution is feasible, but I hope that springboot can simplify the implementation, and the implementation is the best as @wilkinsona and @bono007 replies
Comment From: onobc
I was going to suggest that using the property form for auto-config exclusion
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration
would be the same mechanism (setting a property) and have the same effect as setting the proposed property
spring.redis.client.type=jedis
with the caveat that it's not straightforward that those mean the same thing.
However, I went to verify this approach and realized that there is no LettuceAutoConfiguration
. RedisAutoConfiguration
imports both Lettuce and Jedis configuration. Exclusion ends w/ the following:
java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes:
- org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration
Comment From: snicoll
Just like spring boot, it supports specifying the DataSource type.
I don't think that's a valid analogy. As we've indicated above, Jedis is not being actively maintained these days and it's not unlikely we would deprecate its support and ultimately remove it from Spring Boot in a future release. Introducing now a property that makes it look like it's actively supported (like the connection pools are) is misleading to our users. We've actually discussed this at our team meeting last week and are in agreement not to introduce this property if there is a reasonable way to opt-out from Lettuce.
However, I went to verify this approach and realized that there is no LettuceAutoConfiguration. RedisAutoConfiguration imports both Lettuce and Jedis configuration.
Thanks @bono007, I overlooked this part when I suggested to exclude the lettuce auto-configuration. We'll have to discuss this one some more then.
Comment From: brucelwl
@snicoll I want to know why springboot does not support jedis in a future release. It seems that jedis is better than lettuce in the case of cluster topology changes
Comment From: onobc
@snicoll it would be low effort for me to move the connection configs to 1st class auto-configs and break the manual imports from RedisAutoConfiguration
. That would allow the suggested workaround.
Comment From: mp911de
It seems that jedis is better than lettuce in the case of cluster topology changes
Care to elaborate @brucelwl? Jedis provides no mechanism to react to topology changes other than MOVED
redirections. Spring Data Redis uses is required to use topology cache that expires after 100ms (by default) which leads to topology polling every 100ms causing a severe load on Redis Clusters.
Lettuce allows for periodic and adaptive topology refresh with a much more fine-grained level of control.
Comment From: brucelwl
@mp911de Thank you for your reply
Comment From: snicoll
We've discussed this one more time and introducing a JedisAutoConfiguration
and LettuceAutoConfiguration
so that users that prefer Jedis while having Lettuce on the classpath feels way more invasive than introducing a property so we'll do that.
Comment From: snicoll
Closing in favour of PR #22569