Search

[Applicaion]14.비동기 구조: 쿠폰 요청 처리 시스템(coupon-api) - Cache 적용

Publish Date
2024/11/22
Status
Done
1 more property
비동기 구조 2단계: Cache
Redis 캐시를 활용해 정적인 데이터(쿠폰 존재, 유효기간)를 빠르게 검증하고, 동적인 데이터(중복 발급, 수량)를 실시간으로 처리하여 쿠폰 발급의 성능과 효율성을 높였다.

비동기 구조 2단계: Cache 적용

데이터 검증 속도를 향상시키기 위해 캐시와 Redis를 각각의 역할에 따라 분리하여 사용하였다. 쿠폰 발급 로직에서는 다음과 같은 유효성 검증이 필수적으로 이루어진다:
검증 항목
내용
특성
처리
쿠폰 존재 검증
쿠폰 ID가 유효한지 확인 (예: 네고왕이벤트, 특별 프로모션 쿠폰)
정적
캐시
쿠폰 유효기간 검증
현재 날짜가 쿠폰 발급 가능 기간 확인 (예: 2024.12.01 ~ 2024.12.31)
정적
캐시
중복 발급 검증
동일한 사용자가 같은 쿠폰을 여러 번 요청했는지 확인
동적
Redis
수량 검증
쿠폰의 남은 발급 수량이 존재하는지 확인
동적
Redis
정적 데이터:
자주 변하지 않는 데이터로,
메모리 기반 캐시를 활용하여 반복적인 DB 조회를 줄이고, 빠르게 데이터에 접근할 수 있다.
처리 항목: 쿠폰 존재 검증, 유효 기간 검증
동적 데이터:
동적 데이터는 실시간으로 변하는 데이터로,
Redis를 활용해 실시간 검증을 수행하여 정확성과 효율성을 높인다.
처리 항목: 중복 발급 검증, 수량 검증
정적 데이터는 캐시, 동적 데이터는 Redis를 통해 각각의 강점을 활용하여 검증 로직의 성능과 정확성을 최적화했다.

소스코드 구현

구조 및 구현

coupon-BE/coupon-core/ ├── build.gradle.kts // 의존성 추가 ├── src/main/java/com/example/couponcore/ │ ├── CouponCoreConfiguration.java // 캐시 활성화 │ ├── configuration/ │ │ └── CacheConfiguration.java // Redis 캐시 설정 │ ├── repository/redis/ │ │ ├── dto/ │ │ │ └── CouponRedisEntity.java // 쿠폰 캐싱 엔티티 │ ├── service/ │ │ ├── CouponCacheService.java // 캐시 서비스 │ │ ├── AsyncCouponIssueServiceV1.java // 비즈니스 로직
Java
복사
파일명
내용
build.gradle.kts
- Jackson 의존성 추가 - JSON 데이터 직렬화 및 역직렬화 지원
CouponCoreConfiguration.java
@EnableCaching 어노테이션으로 캐시 기능 활성화
CacheConfiguration.java
Redis 캐시 설정 (직렬화 및 TTL 설정)
CouponRedisEntity.java
쿠폰의 존재 및 유효기간 검증을 위한 Redis 캐시 엔티티 정의
CouponCacheService.java
쿠폰 정보를 캐시에서 조회하거나 업데이트하는 서비스
AsyncCouponIssueServiceV1.java
- 비동기 쿠폰 발급 로직 처리 - Redis와 캐시를 조합하여 유효성 검증 수행

소스코드

build.gradle.kts(coupon-core)
CouponCoreConfiguration.java
CacheConfiguration.java
CouponRedisEntity.java
CouponCacheService.java
AsyncCouponIssueServiceV1.java

성능테스트

2단계: Cache 적용 (v2.2)

버전 정보

버전
변경 사항
v2.2
비동기 구조 2단계 Cache 적용 - build.gradle.kts - CouponCoreConfiguration.java - CacheConfiguration.java - CouponRedisEntity.java - CouponCacheService.java - AsyncCouponIssueServiceV1.java

테스트 결과

테스트 환경: Local 환경에서 성능 테스트 3회 실시, 평균 값 도출
소스코드 버전정보
인프라 환경
쿠폰 발급 수량 비교 (정상발급확인)
#Request
#Fails
Failures
Average (ms)
RPS
MySQL CPU(%)
Redis CPU(%)
v2.2
localhost
일치
302,494
87
0.03%
1690.48
585.96
60.62
20.39
v2.2 캐시 적용 부하테스트 결과

테스트 결과 요약

Redis 캐시 적용 전후 성능 비교:
항목
v2.1.2(캐시미적용)
v2.2(캐시적용)
비교
RPS (초당 요청 처리)
582.55
585.96
+0.6%
평균 응답 시간(ms)
1699.80
1690.48
-0.5%
MySQL CPU 사용량(%)
95.11%
60.62%
-36.2%
Redis CPU 사용량(%)
20%
20.39%
+1.95%
1.
RPS 증가 및 MySQL 부하 감소
Redis 캐시를 활용해 MySQL CPU 사용량이 60.62%
캐시 미적용과 비교하여 36.2% 감소, MySQL에 대한 부하를 효과적으로 줄임
RPS는 소폭 증가(+0.6%)하여 안정적인 처리 속도를 유지함
2.
평균 응답 시간 개선
응답 시간이 1699.80ms → 1690.48ms (-0.5%)로 미세하게 개선
전체 요청 처리 성능이 더욱 안정화됨
3.
Redis 사용량 유지
Redis CPU 사용량이 20% → 20.39% (+1.95%)로 증가
성능 최적화와 부하 분산에는 영향을 미치지 않음

결론

Redis 캐시는 쿠폰 발급 시스템의 정적 데이터를 효율적으로 관리하여 DB 조회 횟수를 줄였고, 동적 데이터는 Redis의 실시간 처리 능력을 통해 안정적으로 검증되었다. 이로써 대규모 트래픽에서도 높은 처리 속도와 안정성을 유지할 수 있었다. 앞으로 RPS를 더욱 높이기 위해 Redis 스크립트 및 추가적인 최적화를 검토할 예정이다.
Redis 캐시를 도입하여 정적 데이터(쿠폰 존재, 유효기간)를 빠르게 검증함으로써 MySQL 부하를 크게 줄이는 데 성공하였다. 전체적인 성능은 안정화되었으며, 실패율이 소폭 증가했지만 이는 트래픽 증가와 Redis 키 TTL 등의 미세 조정으로 해결 가능할 것으로 보인다. RPS 증가와 안정성 확보를 위해 추가 최적화 작업을 계획 중이다.

Q&A

캐시와 Redis를 분리한 이유는?
쿠폰 발급 시스템에서 Redis 키를 관리하는 이유는?
Redis 캐시 적용 시 주의할 점은?
캐시는 Redis 캐시를 의미하는게 맞지?
Search
Main PageCategoryTagskkogggokkAbout MeContact