핫딜 단건 조회 - ekdan38/HotDealService GitHub Wiki
- CPU : Intel i5-8250U 1.6GHz
- RAM : 8GB
- OS : Window10
- Databse : MySQL 8.0
- Test Tool : K6
테스트를 위해 1만개의 핫딜, 10만개의 상품에 대한 더미 데이터를 생성하였다.
테스트 시나리오
핫딜 단건 랜덤 조회
개선 전 k6 테스트
k6 테스트 결과
-
VU 100
-
VU 200
-
VU 300
핫딜 단건 조회 (3분) | 총 처리량 | Latency(mean) | Latency(P95) | TPS |
---|---|---|---|---|
VU 100 | 49632 | 361ms | 642ms | 275 |
VU 200 | 51208 | 702ms | 1.29s | 283 |
VU 300 | 52151 | 1.03s | 2.34s | 288 |
테스트 결과 분석
- VU 100 -> 200 증가시, Latency(mean), Latency(P95) 모두 2배 이상 증가
- VU 200 수준에서 시스템 처리량 한계에 근접
- TPS 증가가 거의 없음
단건 Row 조회이기 때문에 전반적인 성능이 나쁘지 않지만, DTO Projection, 인덱싱, 캐싱으로 성능 개선 시도
성능 개선 계획
- DTO Projection : 단건 ROW를 조회 하지만, 단건 Row도 필요한 필드를 조회하면 성능이 개선되는지 확인
- 인덱싱 : WHERE 조건으로 (deleted, hotdeal_id) 를 사용중 -> deleted 의 카디널리티는 2로, 기존 PK 클러스터링 인덱스 사용
- 캐싱: 반복적으로 조회되는 데이터를 캐시에 저장하여 DB 부하를 줄여 성능 개선
단건 Row 조회이지만, DTO Projection을 통해 필요한 필드만 선택적으로 조회할때 성능 향상이 있는지 확인하기 위해 적용
수정 전
@Query("SELECT h " +
"FROM HotDeal h " +
"WHERE h.deleted = false " +
"AND h.id = :hotDealId")
Optional<HotDeal> findHotDealById(@Param("hotDealId") Long hotDealId);
수정 후
@Query("SELECT new com.hong.hotdealservice.dto.projection.HotDealSimpleDto" +
"(h.id, h.title, h.description, h.startTime, h.endTime) " +
"FROM HotDeal h " +
"WHERE h.deleted = false " +
"AND h.id = :hotDealId")
Optional<HotDealSimpleDto> findHotDealById(@Param("hotDealId") Long hotDealId);
DTO Projection 반영 후 k6 테스트
k6 테스트 결과
-
VU 100
-
VU 200
-
VU 300
핫딜 단건 조회 (3분) | 총 처리량 | Latency(mean) | Latency(P95) | TPS |
---|---|---|---|---|
VU 100 | 51967 | 345ms | 599ms | 288 |
VU 200 | 51819 | 694ms | 1.28s | 287 |
VU 300 | 50847 | 1.06s | 2.36s | 281 |
테스트 결과 분석
Latency
-
Latency(mean)
- VU 100: 361ms → 345ms (약 4.4% 개선)
- VU 200: 702ms → 694ms (약 1.1% 개선)
- VU 300: 1.03s → 1.06s (약 2.9% 악화)
Latency(mean) : 개선 전과 성능이 같음
-
Latency(P95)
- VU 100: 642ms → 599ms (약 6.7% 개선)
- VU 200: 1.29s → 1.28s (약 0.8% 개선)
- VU 300: 2.34s → 2.36s (약 0.9% 악화)
Latency(P95) : 개선 전과 성능이 같음
TPS
- VU 100: 275 → 288 (약 4.7% 증가)
- VU 200: 283 → 287 (약 1.4% 증가)
- VU 300: 288 → 281 (약 2.4% 감소)
TPS : 개선 전과 성능이 같음
개선되거나 악화되는 모습이 보기니하나 이는 테스트마다 결과에 대한 편차가 있는점을 고려하면 Latency, TPS 모두 개선 전과 성능이 같다고 볼 수 있음
1개의 Row 만 가져오기 때문에 효과가 미비하거나 DTO 변환 비용에 대한 오버헤드 발생
[실행 계획]
EXPLAIN SELECT h.hotdeal_id, h.title, h.description, h.start_time, h.end_time
FROM hot_deal h
WHERE h.deleted = false
AND h.hotdeal_id = 8300
PK 클러스터링 인덱스를 타고 있고, ref : const, Extra : null 로 조건문이 단순하여 이미 효율적이라 판단하여 인덱싱 진행하지 않음
캐싱을 통해 DB에 직접 접근하는 대신, In-Memory 수준에서 빠르게 데이터 I/O 처리를 수행함으로써 응답 속도 향상 및 부하 감소 등 성능 개선 효과를 기대
3.1. 캐싱 적용
private HotDealSimpleDto getHotDealAndValidate(Long hotDealId){
// 1. Redis 조회
HotDealCacheDto cachedData = hotDealRedisRepository.findById(hotDealId);
if(cachedData != null){
return new HotDealSimpleDto(cachedData);
}
// 2. cacheMiss -> DB 조회
HotDealSimpleDto hotDeal = hotDealRepository.findHotDealById(hotDealId).orElseThrow(() -> {
log.debug("요청된 핫딜이 존재하지 않습니다. hotDealId = {}", hotDealId);
return new HotDealException(ErrorCode.HOTDEAL_NOT_FOUND, hotDealId);
});
// 3. Redis save
HotDealCacheDto cacheDto = new HotDealCacheDto(hotDeal);
hotDealRedisRepository.saveWithTTL(cacheDto);
return hotDeal;
}
CacheAside 방식을 사용하여 Redis 캐싱 적용
- 핫딜은 자주 변경되는 데이터가 아니라고 판단, TTL 30분 적용
- 일관성을 위해 핫딜에 대한 수정 삭제 발생시 캐시 무효화 처리 캐싱 적용 후 k6 테스트 결과
k6 테스트 결과
-
VU 100
-
VU 200
-
VU 300
핫딜 단건 조회 (3분) | 총 처리량 | Latency(mean) | Latency(P95) | TPS |
---|---|---|---|---|
VU 100 | 120127 | 148ms | 297ms | 666 |
VU 200 | 136463 | 262ms | 523ms | 756 |
VU 300 | 133888 | 401ms | 823ms | 742 |
테스트 결과 분석
Latency
-
Latency(mean)
- VU 100: 361ms → 148ms (약 59.0% 개선)
- VU 200: 702ms → 262ms (약 62.7% 개선)
- VU 300: 1.03s → 401ms (약 61.1% 개선)
Latency(mean) : 전 구간에서 약 60% 이상 개선
-
Latency(P95)
- VU 100: 642ms → 297ms (약 53.7% 개선)
- VU 200: 1.29s → 523ms (약 59.5% 개선)
- VU 300: 2.34s → 823ms (약 64.8% 개선)
Latency(P95) : 약 54 ~ 65% 개선, 절반 이상 개선
TPS
- VU 100: 275 → 666 (약 142.2% 증가)
- VU 200: 283 → 756 (약 167.0% 증가)
- VU 300: 288 → 742 (약 157.6% 증가)
TPS : 약 142 ~ 167% 개선, 최대 2.5배 증가
캐싱을 통해 Latency가 모든 구간 절반 이상 개선되었으며, TPS는 약 142 ~ 167% 개선, 최대 2.5배 향상
항목 | DTO Projection | 캐싱 적용 |
---|---|---|
평균 Latency 감소율 | 거의 없음(개선전과 동일) | 약 60% |
TPS 증가율 | 거의 없음(개선전과 동일) | 약 142 ~ 167% |
- DTO Projection으로 인한 성능 개선 효과 없음
- 인덱스를 통한 성능 개선은 현재 실행 계획이 효율적, 따라서 인덱스 생성하지 않음
- Redis 캐싱 적용을 통해 눈에 띠는 성능 향상을 보임