진짜 개발자
본문 바로가기

FrameWork/Spring Boot

Spring Boot - Redis Cache를 통한 읽기 요청 성능향상

728x90

이번 포스팅에서는, 간단히 Redis 를 이용해, 서비스의 메소드를 캐싱하여, 읽기 성능 향상을 도모해보도록 하겠습니다.


1. 캐싱 대상 메소드

1.1 대상 메소드 간단히 살펴보기

public CategoryDto createCategoryRoot() {
    Map<Long, List<CategoryDto>> groupingByParent = categoryRepository.findAll()
            .stream()
            .map(ce -> new CategoryDto(ce.getCategoryId(), ce.getCategoryName(), ce.getParentId()))
            .collect(groupingBy(cd -> cd.getParentId()));

    CategoryDto rootCategoryDto = new CategoryDto(0l, "ROOT", null);
    addSubCategories(rootCategoryDto, groupingByParent);

    return rootCategoryDto;
}

전체 코드 저장소 : https://gitlab.com/galid1/jpa-study

캐싱할 서비스는 위 메소드 입니다. 수행하는 내용은 아래와 같습니다.

  1. 데이터베이스로부터, 카테고리를 모두 받아옵니다.

  2. parentId(부모 카테고리 id)를 기반으로 그룹화 합니다.

  3. 카테고리에 자식카테고리들을 재귀적으로 넣어주어 rootCategory를 완성합니다.

    https://galid1.tistory.com/774 이 주소에 정리되어 있으니 궁금하시다면 참고하면 될것 같습니다.

중요한 점은 수행시간이 꽤나 걸리는 무거운 작업이라는 점입니다.




1.2 캐싱 전 수행시간

스크린샷 2020-10-30 오후 11.39.34

우선, 캐싱하기 전 성능이 얼마나 나오는지 확인하기 위해, 해당 메소드를 사용하는 쪽에서 콘솔을 이용해 간단히 수행시간을 확인해보겠습니다.



스크린샷 2020-10-30 오후 11.38.44

Millisec 단위로 약 0.2초가 걸렸습니다. 사용자의 요청마다 0.2초가 걸리는 연산이라면 적지 않은 시간이 소모됨을 알 수 있습니다.





2. 캐싱 적용

앞서 말씀 드렸듯 저희는 Redis 를 이용할 것입니다.



2.1 docker를 이용해 redis 서버 생성

https://hub.docker.com/_/redis

docker를 이용해 redis 컨테이너를 우선 생성합니다.



스크린샷 2020-10-30 오후 11.43.51

redis-cli를 이용해 정상적으로 동작중인지 확인합니다.




2.2 spring boot 캐시 적용

@SpringBootApplication
@EnableCaching
public class CommerceApplication {
    public static void main(String[] args) {
        SpringApplication.run(CommerceApplication.class, args);
    }
}

어플리케이션 클래스에 @EnableCaching 어노테이션을 추가합니다.



@Cacheable("categories")
public CategoryDto createCategoryRoot() {
    Map<Long, List<CategoryDto>> groupingByParent = categoryRepository.findAll()
            .stream()
            .map(ce -> new CategoryDto(ce.getCategoryId(), ce.getCategoryName(), ce.getParentId()))
            .collect(groupingBy(cd -> cd.getParentId()));

    CategoryDto rootCategoryDto = new CategoryDto(0l, "ROOT", null);
    addSubCategories(rootCategoryDto, groupingByParent);

    return rootCategoryDto;
}

그리고 캐싱할 대상 메소드에 @Cacheable("KEY")를 추가하면, 끝입니다.




2.3 캐싱 후 수행시간

스크린샷 2020-10-30 오후 11.38.44

캐싱을 적용했다고, 바로 빨라지는 것은 아닙니다. 최초 요청시 해당 메소드가 캐시메모리에 캐싱이 된 후, 이후 요청에 대한 응답이 빨라지는 것 입니다.



스크린샷 2020-10-30 오후 11.46.09

두번째 요청부터는 4millisec으로 굉장히 속도가 빨라졌음을 볼 수 있습니다.