본문 바로가기
Projects/푸하하 - 개인 프로젝트

[리팩토링] 레디스 캐싱을 통한 인증과정 유저정보 조회 속도 개선하기

by 우인입니다 2023. 11. 28.

 

개발환경

Java 17 / Spring Boot 3.x / Spring Security 3.x / MySQL 8.0 / Redis / JWT

 

테스트 DB는 로컬환경에서 진행.

 

현재코드

Spring Security를 통해 인증이 필요한 API의 경우 JWT 토큰을 기반으로 유저정보를 가져온다.

아래는 인증 구현체에서 유저정보를 가져오는 코드.

username을 기반으로 select 쿼리를 보내서 가져온다.

//UserDetailsServiceImpl.java

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("Not Found " + username));

    return new UserDetailsImpl(user);
}

 

 

 

예시 API : 유저 프로필 데이터 GET

 

해당 API로 GET 요청을 보내면 userData와 user객체를 가져와 ResponseDto에 담아 반환한다.

 

이때 처음 인증을 위해 user객체를 가져온다. 뿐만아니라 인증이 필요한  API요청에 항상 요청되기 때문에 잦은 조회가 발생한다고 판단하여 이부분을 캐싱 처리하기로 했다.

 

 

코드 수정

 

Repository의 메소드에 @Cacheable어노테이션을 통해 entity객체를 캐싱하도록 했다.

 


결과 확인

 

 

user객체가 username을 키값으로 Redis에 저장된 것을 확인할 수 있다.

60ms의 응답속도를 갖고 있다.

 

 

다시한번 조회하게 되면 User객체는 캐싱데이터에서 가져오게 된다.

 

쿼리를 보면 userData를 select하는 쿼리가 나온것으로 그전에 등장하던 user select쿼리가 보내지지 않은 것을 확인할 수 있다.

 

응답속도도 46ms로 빨라졌다.

 

 

+ User 객체 조회만 속도 측정하기

user객체 가져오는 시간만 측정해보고 싶었다.

 

간단하게 시스템시간을 이용해서 전, 후시간의 차이를 비교해보기로 했다.

 

DB에서 가져오기

 

캐시에서 가져오기

 

 


 

결론

확실히 빠르다.

하지만 그만큼 데이터의 정합성과 같은 부분에서 조심해야한다.

적절한 데이터에 캐싱처리를 어떠한 전략으로 해야할지 관련 세미나 자료들을 더 찾아보며 보완해야할 것 같다.

 

 

참고링크

https://gngsn.tistory.com/157

 

Spring Cache, 제대로 사용하기

Spring Cache 사용법, Annotation 등을 알아보고 설정 방식을 알아보는 것이 해당 포스팅의 목표입니다. 📌 Spring Cache Series ✔ Spring Cache, 제대로 사용하기 ✔ Caffeine Cache, 제대로 사용하기 1 ✔ Caffeine Cac

gngsn.tistory.com

 


 

추가 : @CachePut을 통해 캐시데이터도 변경해주기

 

현재 DB와 캐시 모두 '의문의아재개그장인'이 닉네임이다.

여기서 DB의 데이터만 바뀌게 되면 두 데이터 사이의 정합성이 깨진다.

 

닉네임을 변경할 수 있는 editMyProfile메소드에 @CachePut을 적용해 캐시의 값도 같이 변경시켜주려 한다.

 

 

PUT 요청을 날렸다

 

적용결과

캐시 데이터에도 같이 수정내용이 적용 됐다.

 

 


추가 : 배포환경에서 테스트

 

캐시 적용 전

 

EC2 인스턴스에 직접보낸 요청 평균 37ms.

 

 

캐시 적용 후

 

오우 이런 더 느려졌다.

 

 

추측

글로벌 캐시의 한계??

이정도로 느리면 쓸 이유가 없다. 글로벌 캐시여서라기엔 이렇게나 느리면 아무도 쓰지않을 텐데..

현재 redis에서 무료로 제공하는 클라우드 저장소를 사용중인데 latency는 작지만 실제 통신에 드는 비용이 커보인다.

 

 

가용영역 차이?

Redis Cloud에서 무료로 제공하는 클라우드의 가용영역은 US-East-1 이다. (미국땅)

EC2 인스턴스의 가용영역은 Northeast-2a (서울땅)

 

(좌) Redis Cloud / (우) EC2 인스턴스

 

아무래도 데이터가 미국땅 건너갔다오느라 느린듯하다.

Redis를 서울 가용영역을 토대로 다시 설치해봐야겠다.

 

 

[다음글에서 수정 계속]

https://thiswooin.tistory.com/135

 

[리팩토링] 깨달음 : 리팩토링을 하기엔 데이터 수가 너무도 적었다

지난 번 Redis 서버가 미국에 있는 바람에 캐싱을 적용하자 오히려 느려졌다(?) https://thiswooin.tistory.com/134 [리팩토링] 레디스 캐싱을 통한 인증과정 유저정보 조회 속도 개선하기 개발환경 Java 17 / S

thiswooin.tistory.com