Redis & Spring Boot

고범수·2023년 6월 29일
2

Spring Boot

목록 보기
4/12

NoSQL에 속하는 Redis를 캐시 서버로 두고, Spring Boot 서버와 연동해 보자. 먼저 Spring Boot와 Redis를 연결해주는 Spring Data Redis의 특징을 살펴보자.

Spring 은 Spring application이 Redis에 쉽게 접근하고 설정할 수 있도록 Spring Data Redis를 제공한다. Spring Data Redis는 저수준, 고수준 추상화를 통해 사용자로 하여금 인프라를 고려하지 않아도 되게끔 만든다.

Redis와 Java를 연결하는 Connector에는 대표적으로 두 종류가 있다. 바로 Lettuce와 Jedis이다. Lettuce가 더 많은 기능을 제공하고, 오픈소스로 잘 관리되고 있다고 하며, 무엇보다 Spring에서 Lettuce를 권장한다(Spring Data Redis 의존성을 추가하면 Lettuce가 디폴트로 추가된다. Jedis는 별도로 의존성 추가해야 함).

Spring Data Redis는 Redis driver exceptions들을 Spring의 exception으로 translation 해준다.

다음으로, Spring Data Redis를 이용하여 Spring Boot와 Redis를 연동시켜보도록 한다.

아래 이미지처럼 Spring Data Redis 의존성 추가. 자동으로 Connector인 Lettuce도 추가된다.

아래 이미지처럼 application.yml 파일에 Redis 서버 설정값 추가. 6379가 기본 포트다.

Redis는 NoSQL이면서 In-memory DB다. DB이므로 설치한다.
Redis를 설치하고 실행하면 아래와 같은 화면이 나온다.

Spring은 Cache Abstraction(캐시 추상화)를 제공한다. 즉, 최소한의 코드변화만으로 다양한 종류의 캐싱 솔루션들을 사용할 수 있다. 그리고 Spring Redis가 바로 이 Spring cache abstraction의 구현체를 제공한다.

여기에 더해서 Spring은 caching을 AOP로 구현했기 때문에 기존 Spring application코드에 큰 변화 없이 caching을 추가할 수 있다.

Spring Data Redis Cache Abstraction 참고

https://docs.spring.io/spring-data/redis/docs/2.7.13/reference/html/#redis:support:cache-abstraction

Cache Abstraction 참고
https://docs.spring.io/spring-framework/docs/5.0.0.M5/spring-framework-reference/html/cache.html

Spring Redis가 Spring cache abstraction의 구현체를 제공하기 때문에 Spring cache abstraction의 기능을 사용하여 Redis를 편하게 사용할 수 있다. 아래 이미지 처럼 어노테이션을 이용하여 쉽게 캐싱을 적용할 수 있다.

이 중에서 사용해볼 @Cacheable을 살펴보자. 아래 이미지처럼 설명이 공식 문서에 적혀있으니 참고하며 기존 Spring application에 Redis 서버를 이용한 caching을 적용해보자.

Cache Abstraction @Cacheable annotation 참고
https://docs.spring.io/spring-framework/docs/5.0.0.M5/spring-framework-reference/html/cache.html

보통은 메서드 단위로 캐싱을 적용한다. @Cacheable 어노테이션은 적용된 메서드의 파라미터 값들의 KeyGenerator의 버전에 따라 파라미터가 2개 이상인 경우 해시코드 값을 Key-Value의 key로 사용하거나, compound key를 key로 사용한다.

즉, 메서드의 파라미터가 여러개라면 기본동작은 모든 파라미터를 key 값으로 사용한다.

만약 메서드의 특정 파라미터만 사용하고 싶다면 아래 이미지처럼 key 값을 설정해주면 되는데, 이 때 Spring Expression Language (SpEL)를 사용한다.

만약 아래 이미지처럼 @Cacheable 어노테이션을 추가했다면, Redis에는 어떤 형태로 저장이 될까?

key = 'cacheNames::key'
value = 해당되는 Object(Serialized)

위 같은 형태로 Redis에 저장된다.

캐싱은 거의 변하지 않거나 자주 사용되거나 부하가 큰 데이터인 경우에 적용하는 것이 효과가 크며 바람직하다. 데이터가 변하여 캐싱된 값과 달라지면 어떻게 해야 할까? 캐싱된 기존 데이터를 지워야 한다. 이 때 사용할 수 있는 어노테이션이 바로 @CacheEvict 어노테이션이다.

아래 이미지 처럼 캐싱을 적용하면 정말로 DB로의 쿼리가 줄어들까?

위 메서드를 2번 호출한 결과가 아래 이미지이다. attraction을 select하는 쿼리가 맨 처음 한 번 수행되고, 두 번째 호출에서는 쿼리가 수행되지 않았다. 캐싱된 데이터를 사용했다는 것.

실제로 캐싱된 데이터를 Redis 에서 조회해 보았다.

Redis 서버가 In-memory DB이기 때문에 Disk에서 불러오는 것보다는 빠르지만, 요청이 많아지면 당연히 Redis 서버도 요청이 적을 때보다 응답이 느려질 수 밖에 없다. 이 때는, Redis Cluster를 고려해볼 수 있다.

이 밖에 Redis Repository를 이용해서 Cache가 아닌 저장소 용도로 Redis를 사용할 수 있다. 코드는 JPA Repository와 비슷하다.

0개의 댓글