Skip to content

Conversation

@eggnee
Copy link
Member

@eggnee eggnee commented Jan 18, 2025

✅ What is this PR

  • Redis를 활용하여 쿠폰 수량 및 상태를 캐싱하고, 발급 이력을 임시 저장한 뒤, 주기적으로 DB에 반영합니다. 이를 통해 DB 부하를 줄이고 성능을 최적화합니다.

📄 Changes Made

  • Redis를 통해 쿠폰 수량 및 상태를 캐싱하는 로직 추가
  • 쿠폰 발급 시 Redis에서 수량 감소 및 상태 변경을 처리하도록 구현
  • 쿠폰 발급 시 중복 사용자를 검증하는 로직 추가
  • 스케줄러를 통해 Redis에 저장된 발급 이력을 주기적으로 DB로 이관

🙋🏻‍ Review Point

리뷰어가 확인해야 할 사항 코멘트

  • 더티 체킹 문제 방지를 위해 CouponCache 객체를 사용하였는데 이에 대해 어떻게 생각하시는지 궁금합니다! 자세한 내용은 commit 메시지를 확인해주시면 감사하겠습니다.

Issue

기존 Redisson 분산 락 방식의 DB 부하 문제 해결
- 분산 락으로 인한 DB 부하 한계를 개선하기 위해 Redis 캐싱 도입
- Redis 캐싱을 통해 쿠폰 발급 수량 및 상태를 캐싱하여 발급을 수행하고, 잔여 수량 부족 시 즉시 예외를 반환하도록 변경
- 로직 변경에 따른 컨트롤러 수정사항 반영
- 기존의 분산 락 코드 제거
- Redis 저장 시 JSON 직렬화를 위한 설정 추가
- isZero() 메서드로 인한 직렬화 문제를 해결하기 위해 메서드명을 checkIsZero 로 변경

Coupon 캐싱 구조 개선
- 더티 체킹 문제 방지를 위해 CouponCache 객체를 사용하고, 이를 통해 Redis에 저장
- CouponCache 클래스에 비즈니스 로직을 구현하여 쿠폰 발급을 처리
- CouponPrefix 클래스를 생성하여 Redis 키 네이밍을 일관되게 관리
기존의 단일 Coupon 서비스를 기능별로 분리
- CouponCreateService, CouponIssueService, CouponExpireService 로 세분화

쿠폰 상태가 만료로 변경될 경우 Redis에 캐싱된 데이터를 삭제하는 로직 추가
- 현재는 메서드를 직접 호출하여 처리
- 추후 이벤트 핸들러를 활용한 비동기 처리로 전환 예정
RTransaction을 활용하여 Redis 트랜잭션 처리 적용
- 기본 Redis 트랜잭션은 완전한 원자성을 보장하지 않으므로 RTransaction을 사용하여 트랜잭션 원자성 보장

쿠폰 캐시 TTL 적용
- RTransaction 내에서는 TTL 설정이 불가능하여 트랜잭션 종료 후 캐시에 TTL을 설정하는 방식으로 처리
발급 쿠폰 데이터 구조 변경
- 기존 Set 기반 구조 (coupon:issuer:1 - 1, 2, 3)를 HashMap 기반 구조 (coupon:issuer - (1 - 1, 2, 3))로 변경하여 쿠폰 ID별 데이터 생성 가능

DB로 데이터 이관 및 쿠폰 수량 감소
- 이관 시 실제 DB에 저장된 쿠폰 수량을 정확히 감소하도록 처리

캐시 데이터 삭제
- DB로 데이터 이관 완료 후 기존 캐시 데이터를 삭제하는 로직 추가

중복 사용자 검증 로직 개선
- 기존에는 coupon:issuer 캐시에서만 중복 검증을 수행했으나, DB와 캐시 간의 중복 사용자를 모두 검증할 수 있도록 CouponCache에 Set<Long> issuerIds를 추가하고 검증 로직 수정
@eggnee eggnee added 🔥 Enhance 성능 개선 ✨ Feat 기능 개발 🔨 Refactor 리팩토링 labels Jan 18, 2025
@eggnee eggnee requested a review from re-mora January 18, 2025 06:17
@eggnee eggnee self-assigned this Jan 18, 2025
RTransaction은 Redis 명령어를 원자적으로 실행하지만, 락을 걸지 않아 다른 트랜잭션의 명령어와 교차 실행될 수 있어 동시성 문제가 발생함
- 이를 해결하기 위해 쿠폰 발급 시, RLock을 사용하여 couponId에 대한 락 설정
- 발급된 쿠폰을 캐시에서 DB로 이관할 때도 동시성 문제가 발생할 수 있으므로 couponId에 대한 락 추가
- RLock을 제공하는 RedissonLockManager 클래스 구현
RTransaction은 Redis 명령어를 원자적으로 실행하지만, 락을 걸지 않아 다른 트랜잭션의 명령어와 교차 실행될 수 있어 동시성 문제가 발생함
- 이를 해결하기 위해 쿠폰 발급 시, RLock을 사용하여 couponId에 대한 락 설정
- 발급된 쿠폰을 캐시에서 DB로 이관할 때도 동시성 문제가 발생할 수 있으므로 couponId에 대한 락 추가
- RLock을 제공하는 RedissonLockManager 클래스 구현
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔥 Enhance 성능 개선 ✨ Feat 기능 개발 🔨 Refactor 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant