RedisTemplate (Spring Redis) 사용법
Goal
- Kopring 상황에서의 redisTemplate 기본세팅 및 사용법을 정리해봅니다.
기본 설정
- 자세한 설정은 Github 을 참고하시는것을 권장드립니다.
Infra 설정
1 |
|
- redis 를 로컬에 띄우기위한 기본적인
docker-compose
입니다.
1 |
|
Spring 설정
1 |
|
1 |
|
1 |
|
RedisConnectionFactory
빈을 먼저 만들어줍니다.- 이후
RedisConnectionFactory
를 사용하는redisTemplate
빈을 만들어주어 기본적인 RedisTemplate 를 사용할 수 있습니다. StringRedisSerializer()
는 serializer 설정을 해주는것인데, 생략할시 redis 콘솔에서 출력했을때"\xac\xed\x00"
같은 값이 prefix 에 붙어 노출되게 됩니다. 관련 docs
StringRedisSerializer
를 생략한 경우
value가 String 형태의 저장/조회
만들어준 redisTemplate 사용
1 |
|
RedisConfig
에서 만들어준redisTemplate
를 주입받아서 사용할 수 있습니다.opsForValue()
를 이용해서 key, value 를 넣어줄 수 있는ValueOperations
를 획득할 수 있습니다.- 조회의 경우에는
get
or[]
를 이용해서 할 수 있습니다.
1 |
|
String 특화 StringRedisTemplate 사용
1 |
|
1 |
|
- config 에서 설정/주입한 RedisTemplate 빈 말고도, 기본적으로 제공하는
StringRedisTemplate
를 이용할 수 도 있습니다.
Set
1 |
|
- set 의 경우
opsForSet()
를 호출해서 Set 을 다를 수 있는valueOperations
를 얻을 수 있습니다. - key 하나에 여러값을 담을 수 있습니다.
- 조회시에는
members(key)
를 통해서 보유하고 있는 values 를 획득 할 수 있습니다.
1 |
|
Hash
1 |
|
- 해시의 경우 해시 해시에 대한 key, value 도 serializer 설정을 해주어야 해시값을 제외한 값을 명확히 볼 수 있습니다.
1 |
|
opsForHash
을 이용해주면됩니다. 이때,<HashKeyType, HashValueType>
을 넣어줄 수 있습니다.- 삽입의 경우에는
hashOperations.put(key, hashKey, value)
형태로 사용합니다. - 조회시에는
hashOperations.entries(key)
를 통해서 key 에 해당하는 해시키를 찾은뒤,entries[hashKey]
를 통해서 value 에 접근할 수 있습니다.
1 |
|
만료시간 설정
1 |
|
redisTemplate.expire(key, 3, TimeUnit.SECONDS)
처럼 key 에 따른 만료시간을 설정해줄 수 있습니다.
Value 가 Object 형태일때
아래에서 설정하는 방법은 객체별로 필요한 RedisTemplate 를 매번 새롭게 만들어줘야하고, pakage 경로가 같이 Redis 에 저장된다는 이슈가 있어 추천하지 않습니다. 객체 형태로 저장이 필요한경우에는 아래 내용보다, 해당 포스팅 에 기재된 방법을 사용하시는걸 권장드립니다.
설정
1 |
|
- 저장되는것이 Object 인 형태인 경우에는, 직렬화가 가능하도록
Serializable
을 반드시 붙여주어야합니다.
1 |
|
- Object 저장을 할 수 있는 RedisTemplate 를 하나 새롭게 구성해줍니다.
1 |
|
- 중요한것은
jascksonObjectMapper
을 명시적으로 설정 해주어야합니다. - 해당 설정이 없으면, 조회시
deserialize
과정에서 기본생성자가 없다는 에러가 발생하게 됩니다.
org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of …
org.springframework.data.redis.serializer.SerializationException: (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
1 |
|
- 또 다른 방법으로는 디폴트값을 명시적으로 넣어준다면, 자동적으로 디폴트 생성자가 생성되어 위와같은 에러가 발생하지 않게 됩니다.
기본적으로 SpringBoot 설정에 들어가있는
jackson-module-kotlin
이 존재한다면, spring jackson 에서 사용하는 리플랙션을 위해 자동으로 디폴트 생성자 처리를 해주게되는데, redisTemplate 설정에서는 자동으로 설정이 되지 않아서 이런문제가 발생하게 됩니다. 관련된 글은 이곳을 참고하시면 되시겠습니다.
삽입, 조회
1 |
|
- 설정 부분만 제대로 해주었다면, String 다루듯이 동일하게 처리하면됩니다.
1 |
|
삭제
1 |
|
- RedisTemplate 혹은 valueOperations 를 이용해 redis key, value 를 삭제할 수 있습니다.
테스트환경에서 주의할점
redis 에 저장하는 결과는 트랜잭션 롤백이 되지않음.
- 테스트내에서
@Transactional
을 사용해도 redis 에 저장되는 데이터들은 기본적으로 롤백되지 않습니다. - 즉 테스트에서 저장한 데이터가 다른 테스트에 영향을 줄 수 있는 환경입니다. (멱등성 지켜지지 않음.)
1 |
|
- 이 부분을 해결하기 위해 테스트 전, 후로 flushAll() 을 호출해, redis 내의 데이터를 비워주시는것을 권장 드립니다.
[TIP] Redis cli 기본 명령어
타입확인
1 |
|
저장
1 |
|
String 조회, 삭제
1 |
|
1 |
|
Set 조회, 삭제
1 |
|
Hash 조회, 삭제
1 |
|
전체 키 삭제
1 |
|
Conclusion
- 세팅시에 hash 와 관련된 값들은
StringRedisSerializer()
를 명시적으로 넣어주어야한다. - String 사용시
stringRedisTemplate
를 이용할 수 있다. - Object 형태를 직렬화하여 저장할시,
Jackson2JsonRedisSerializer
와setObjectMapper(jacksonObjectMapper())
를 명시적으로 넣어주어야 한다. - 테스트내에서 Redis 에 저장딘 데이터는 롤백되지 않는다.
Code
- 관련된 코드는 Github 에서 볼 수 있습니다.
Reference
- https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/
- https://redis.io/commands/
- https://bcp0109.tistory.com/328
- https://dev-monkey-dugi.tistory.com/150
- https://unluckyjung.github.io/spring/2023/11/26/redis-template-wrapping/