프로젝트 설명: 인프런 강의 에서 제시된 선착순 100명의 할인쿠폰 제공 이벤트 시스템 구현
선착순 100명에게 할인쿠폰을 제공하는 이벤트를 진행하고자 한다.
- 100장 이상의 쿠폰이 발행
- 이벤트 페이지 접속 불가
- 서버의 모든 응답 지연
- 할인 쿠폰을 첫 100명의 고객에게만 제공하도록 보장하며, 100개 이상의 쿠폰 발행을 방지
- 이벤트의 영향을 이벤트 페이지로만 제한하여 참여하지 않는 사용자의 사용자 경험을 보호
- 서버의 안정성과 이벤트의 성공을 보장하기 위해 트래픽의 급격한 증가를 효과적으로 처리
public void apply(Long userId){
long count=couponRepository.count();
if(count>100){
return;
}
couponRepository.save(new Coupon(userId));
}
경쟁 상황(Race Condition) 때문에 데이터 정합성 문제 발생
- 여러 요청이 동시에 apply 메서드를 호출할 경우
- 쿠폰 수량을 확인(count())하고 쿠폰을 발급(save)하는 사이에 다른 요청이 쿠폰을 발급받을 수 있습니다.
- 이로 인해 총 쿠폰 수량이 100개를 초과할 수 있습니다.
- 경쟁 상황: 2개 이상의 스레드가 공유 데이터에 접근하고 동시에 작업을 할 때 발생하는 문제
목적: 쿠폰 발급 과정의 빠른 처리 및 경쟁 상황 방지
장점:
- 쿠폰 발급이 신속하게 이루어집니다.
- 쿠폰 수량 확인 및 발급 과정이 하나의 트랜잭션으로 관리되어 데이터 일관성을 유지합니다.
단점:
- Redis에 쿠폰 수량 정보를 저장하는 추가 작업이 필요합니다.
- Redis 서버 장애 시 발급 시스템에 영향을 줄 수 있습니다.
목적: 데이터베이스의 데이터 일관성 및 경쟁 상황 방지
장점: 쿠폰 발급 과정 중 데이터 불일치의 위험이 줄어듭니다. 단점: 데이터베이스의 트랜잭션 부하로 인해 쿠폰 발급 속도가 저하될 수 있습니다.
목적: 동시성 문제 해결
단점:
- 쿠폰 조회 및 발급 시 락으로 인한 성능 저하 발생
- 락 대기 시간이 길어질 수 있어 사용자 경험 저하 위험
목적: 멀티 쓰레드 환경에서의 동기화
단점:
- 다중 서버 환경에서는 race condition 발생 위험 있음
- 확장성 및 병렬 처리에 한계
목적: 동시성 문제 해결을 위한 가장 간단한 방법
단점:
- 사용자가 많을 경우 대기 시간 증가로 인한 성능 저하 발생
- 확장성 문제로 인해 대규모 서비스에 부적합
장점:
- 처리량을 조절할 수 있다.
- DB에 부하를 줄일 수 있다. 단점: 처리가 지연될 수 있다.
락: kafka를 사용하면 처리가 지연되어 2개의 쿠폰이 발급될 수 있다. 락 범위가 넓어 성능이슈가 발생할 수 있다. set자료구조 - Redis