목적
- 마이페이지 조회 시 반복적으로 DB를 조회하게 되어 성능 저하가 발생
- 이를 개선하기 위해 로컬 캐시(Ehcache)를 적용하여 DB 조회 횟수를 줄이고 응답 속도를 최적화하고자 함
캐시 선택 (Ehcache vs Redis)
- Ehcache 선택 이유
- 로컬 캐시로, 외부 캐시 서버를 별도로 두지 않아도 돼서 설정이 간단하고 비용 절감
- 응답 속도가 빠르며, 애플리케이션 서버에 직접 캐싱하여 네트워크 요청이 필요 없음
- 지속적으로 갱신되는 마이페이지 데이터 특성상, 짧은 TTL 설정으로 캐시 활용도와 일관성 유지
- Redis와의 비교
- Redis는 분산 캐시로 여러 서버 간 캐시 일관성을 보장하고 큰 데이터 세트도 효과적으로 캐싱 가능
- Ehcache는 분산되지 않기 때문에 서버 로컬 캐시용으로 적합하며, 데이터 일관성을 관리하기 쉬움
- Redis에 비해 설정 및 유지 관리가 간편하고 서비 비용을 절감할 수 있어 작은 프로젝트나 분산 필요가 없는 서비스에 적합
준비 단계
- 더미데이터 생성할 클래스 파일 작성(DataInitializer 클래스 파일)
package com.sparta.doguin.config;
import com.sparta.doguin.domain.user.entity.User;
import com.sparta.doguin.domain.user.enums.UserRole;
import com.sparta.doguin.domain.user.enums.UserType;
import com.sparta.doguin.domain.user.repository.UserRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
public class DataInitializer {
@Bean
public CommandLineRunner loadData(UserRepository userRepository) {
return args -> {
for (int i = 1; i <= 1000; i++) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode("password!!!" + i);
User user = User.createUser(
null,
"user" + i + "@example.com",
encodedPassword,
"User" + i,
UserType.INDIVIDUAL,
UserRole.ROLE_USER,
"profile" + i + ".png",
"Hello, I am User" + i,
"Address " + i,
"https://github.com/user" + i,
"https://blog.example.com/user" + i
);
userRepository.save(user);
}
System.out.println("더미데이터 저장 완료.");
};
}
}
2. 더미데이터를 만들고 “캐시 적용 전” 테스트를 한다.(저는 포스트맨으로 진행하였습니다.)
3. 캐시 적용을 위해 의존성을 추가한다.
// Encache
implementation 'org.ehcache:ehcache:3.10.0'
implementation 'javax.cache:cache-api:1.1.1'
implementation 'org.springframework.boot:spring-boot-starter-cache'
4. xml 환경변수 설정(기존에 있는 xml에 추가해준다.)
<cache alias="mypageCache">
<key-type>java.lang.String</key-type>
<value-type>java.lang.Object</value-type>
<expiry>
<ttl unit="minutes">7</ttl>
</expiry>
<resources>
<heap unit="entries">50</heap>
<offheap unit="MB">100</offheap>
</resources>
</cache>
5. 애플리케이션 시작파일에서 @EnableCaching이 있는지 확인해준다.
6. 적용할 서비스 로직에 캐시를 적용한다.
@Cacheable(value = MAPAGE_CACHE, key = "'마이페이지조회'+(#authUser != null ? #authUser.userId : 'anonymous')")
7. 이제 캐시 적용 후의 성능 비교를 한다.
적용 결과
- 성능 테스트 결과
- 적용 전
1차 - 첫 번째 요청 88.03 ms 2차 - 두 번째 요청 15.59 ms
- 적용 전
- 적용 후
1차 - 첫 번째 요청 116.73 ms
2차 - 두 번째 요청 3.82 ms
'TIL(Today I Learned)' 카테고리의 다른 글
[TIL] Local에서 Locust 설치 및 사용법 (2) | 2024.11.08 |
---|---|
[Spring] 프로젝트에서 OAuth 소셜 로그인 적용하기: 카카오, 네이버, 구글, 깃허브 사례 (0) | 2024.10.29 |
[Spring] 스프링에서 알아두면 좋은 어노테이션(Annotation) 모음 (0) | 2024.10.26 |
[Spring Boot] 포스트맨으로 테스트하기 쉽게 환경변수 설정과 'Barere 접두사'를 제거한 순수한 토큰 헤더로 받기 (0) | 2024.10.25 |
[Spring] QueryDSL 관련 코드 정리 (2) | 2024.10.10 |