비동기 구조 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 캐시를 의미하는게 맞지?
Related Posts
Search