자바 Redis Client

jedis github

lettuce github

lettuce spring

자바에서 Redis를 쓸 때 대표적으로 2개의 클라이언트가 있다.

Jedis와 lettuce

Lettuce - Advanced Java Redis client 라 소개 되어있으며, 비동기를 지원한다. 또한 스프링부트 2.0 위의 버젼부터는 lettuce를 기본적으로 redis client로 사용하고 있다. 즉…. Redis를 사용할 때 lettuce를 쓰자이다.. 물론.. 이미 부트 2.0에서 lettuce를 default로 물고 있으니 자연스럽게 2.0버젼부터는 쓰게 될것이다.

Lettuce is a scalable thread-safe Redis client based on netty and Reactor. Lettuce provides synchronous, asynchronous and reactive APIs to interact with Redis.

2.0 이하 버젼에서 lettuce를 적용해본적은 없으나 지금 테스트 해보는 부분은 부트2.0 이상이다.

간단 Spring boot 2.0 redis 설정

블로그를 어디 찾다가 보면 무료 redis cloud를 쓸수 있지만 귀찮으므로 내장 redis를 활용해보자.. 상용환경에서는 절대 쓰면 안된다.

코드는 kotlin으로 작성

EmbeddedRedisConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@Configuration
class EmbeddedRedisConfig {

@Value("\${spring.redis.port}")
private val redisPort: Int = 0

private var redisServer: RedisServer? = null

@PostConstruct
@Throws(IOException::class)
fun redisServer() {
redisServer = RedisServer(redisPort)
redisServer!!.start()
}

@PreDestroy
fun stopRedis() {
if (redisServer != null) {
redisServer!!.stop()
}
}
}

1
2
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
compile group: 'it.ozimov', name: 'embedded-redis', version: '0.7.2'

build.gradle추가

A - Lettuce 설정

아래와 같이 default spring redis client인 lettuce설정

정상적으로 작동함을 확인 할수 있으며 물론 CacheErrorHandler 오버라이드 해서 반드시 더 자세한 에러처리를 해야한다.

또한 value 시리얼라이져를 왜 잭슨 2로 해야 하는지 고민해야한다. 다른것으로 해보고 테스트 해야하지만 이번 블로그는 이와 해당내용되지 않기 때문에 패스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Configuration
@EnableRedisRepositories
@EnableCaching
class RedisConfig : CachingConfigurerSupport() {
@Value("\${spring.redis.host}")
private val redisHost: String? = null

@Value("\${spring.redis.port}")
private val redisPort: Int = 0

@Value("\${spring.redis.password}")
private val redisPassword: String? = null

@Bean()
fun lettuceConnectionFactory(): RedisConnectionFactory {


return LettuceConnectionFactory(redisHost!!, redisPort)
}

@Bean("redisTemplateWithLettuce")
fun redisTemplateWithLettuce(

): RedisTemplate<*, *> {

val template = RedisTemplate<String, Any>()
template.keySerializer = StringRedisSerializer()
template.valueSerializer = GenericJackson2JsonRedisSerializer()
template.hashKeySerializer = StringRedisSerializer()
template.hashValueSerializer = GenericJackson2JsonRedisSerializer()

template.setConnectionFactory(lettuceConnectionFactory())
template.setEnableTransactionSupport(true)


return template
}
}

B - Jeddis 설정

아래와 같이 설정하면 에러가 발생한다 왜일가?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 @Configuration
@EnableRedisRepositories
@EnableCaching
class RedisConfig : CachingConfigurerSupport() {
@Value("\${spring.redis.host}")
private val redisHost: String? = null

@Value("\${spring.redis.port}")
private val redisPort: Int = 0

@Value("\${spring.redis.password}")
private val redisPassword: String? = null

@Bean()
fun jedisConnectionFactory(): JedisConnectionFactory {

val redisStandaloneConfiguration = RedisStandaloneConfiguration(redisHost!!, redisPort)
redisStandaloneConfiguration.setPassword(redisPassword)

return JedisConnectionFactory(redisStandaloneConfiguration)
}

@Bean("redisTemplateWithJedis")
fun redisTemplateWithJedis(

): RedisTemplate<*, *> {

val template = RedisTemplate<String, Any>()
template.keySerializer = StringRedisSerializer()
template.valueSerializer = GenericJackson2JsonRedisSerializer()
template.hashKeySerializer = StringRedisSerializer()
template.hashValueSerializer = GenericJackson2JsonRedisSerializer()

template.setConnectionFactory(jedisConnectionFactory())
template.setEnableTransactionSupport(true)

return template
}
}
1
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cacheManager' defined in class path resource [org/springframework/boot/autoconfigure/cache/RedisCacheConfiguration.class]: Unsatisfied dependency expressed through method 'cacheManager' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jedisConnectionFactory' defined in class path resource [com/beanbroker/sample/config/cache/RedisConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.redis.connection.jedis.JedisConnectionFactory]: Factory method 'jedisConnectionFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: redis/clients/jedis/Tuple

스프링 2.0이상으로 올라오면서 jedis와 관련된 dependency를 추가해주지 않으면 deprecated되었기 때문에 올릴수가 없다. 아래와 같이 build.gradle에 추가하고 사용해야한다.

1
implementation 'redis.clients:jedis'

스프리 부트1.5에서 정말 만약에 2.0으로 올렸을 경우 너무나도 많은 설정이 변경되어야 한다. 가능할지는 모르겠지만….

끝으로 물론 성능 테스트나 다른 테스트를 진행해야 하지만 이미 많은 선배개발자들이 성능관련 테스트를 이미 많이 진행해주었기에 글을 마치며! 사실 예외와 관련된 글을 쓰려고 하였으나 너무나……. 부족하여.. 블로그에 올릴수가 없다…

code sample github