쿠폰 API 서버 구조
1. 유저가 api 서버로 요청을 보낸다
2. API 서버에서 요청을 처리한다.
3. 요청을 처리하는 과정에서 데이터베이스를 사용해 트랜잭션을 처리한다.
- 쿠폰 조회
- 쿠폰 발급 내역 조회
- 쿠폰 수량 증가 & 쿠폰 발급
우리는 N개의 요청을 처리 하길 바라는데 이것이 가능한가?
-> DB는 감당하지 못함.
고로, 유저 트래픽을 감당할 수 있는 구조로 변경해야한다.
쿠폰 API 서버 구조 개선
유저 트래픽 처리
1. N명의 유저가 요청을 보낸다.
2. API 서버에서는 N개의 요청을 처리한다.
3. redis 에서 요청을 처리하고 쿠폰 발급 대상을 저장한다.
4. 쿠폰 발급 처리 기능에서 redis 에 쿠폰 발급 대상을 조회해 발급 처리한다.
redis를 인터페이스로 해서, 발급 서버를 분리하였다.
api server는 쿠폰 발급 요청을 받는 역할만 한다.
발급 서버를 따로 둬서 레디스를 확인, 발급 대상이 있는지 확인하고 쿠폰 발급에 대한 트랜잭션을 한다.
1. N명의 유저가 요청을 보낸다.
2. API 서버에서는 n개의 요청을 처리한다.
3. redis에서 요청을 처리하고 Queue 에 발급 대상을 저장한다.
4. 쿠폰 발급 처리 서버에서는 Queue 를 조회, 발급 처리한다.
이 구조의 핵심은
- 유저 트래픽과 쿠폰 발급 트랜잭션 분리
- redis 를 통한 트래픽 대응
- MySql 트래픽 제어
- 비동기 쿠폰 발급 시스템
- Queue 를 인터페이스로 발급 요청/ 발급 과정 분리
- 쿠폰 발급 요청을 처리하는 API 서버/ 쿠폰 발급을 수행하는 발급 서버 분리
이 구조를 개발 하려면
- MySql 조회 없이 redis 만 사용해 사용자 요청 처리를 할지?
- 쿠폰 기한 검증
- 쿠폰 발급 수량 검증
- 중복 발급 검증
- 위를 redis로 어떻게 처리할 것인지?
Redis 데이터 구조 결정
시스템 구조:
유저의 요청은 API server에서 처리 하고, 그 트래픽을 redis 로 대응한다.
redis 를 통해 쿠폰 발급에 대한 요청을 처리한다.
적절한 유저의 요청은 쿠폰 발급 대기열 Queue 에 적재하고,
이 Queue 를 인터페이스로 하고 있는 발급 서버에서 해당하는 쿠폰 발급 대상을 읽은 후, 쿠폰 발급 트랜잭션을 처리한다.
redis에서 유저의 요청에 대한 트래픽에 대응을 할 수 있어야 한다.
쿠폰 발급 기능 분석
검증
- 쿠폰 존재 검증
- 쿠폰 발급 유효 기간 검증
- 쿠폰 발급 수량 검증
- 중복 발급 검증
발급
- 쿠폰 발급 수량 증가
- 쿠폰 발급 내역 기록
Redis Cache
coupon 엔티티 캐시
-> 검증에 활용할 수 있을까?
- 쿠폰 존재 검증
- 쿠폰 발급 유효 기간 검증
쿠폰 발급 수량 검증- 발급 수량은 실시간성으로 변경되는 값
-> coupon 엔티티 캐시 활용
- 쿠폰 존재 검증
- 쿠폰 발급 유효 기간 검증
쿠폰 발급 수량 관리
- 쿠폰 발급 수량 검증
- 중복 발급 검증
- 쿠폰 발급 수량 증가
- 쿠폰 발급 내역 기록
List
- stack, Queue 구현 가능.
- 중복을 허용
선착순 조건 처리
- 유저 요청에 대한 Queue 구현
1. 유저 요청( coupon_id, user_id)
2. List에 추가 ex_ RPUSH
- 요청에 따라 Queue 를 구현 할 수 있음
발급 수량 관리
1. 유저 요청이 들어옴 (coupon_id, user_id)
2. 발급 수량 조회 및 검증 ex)LLEN
- List는 중복을 허용하므로 unique 한 요청의 수를 구분하기 어려움
3. 중복 발급 검증 ex)LPOS
- O(N) 탐색이 지속적으로 필요하다. 시간 복잡도가 높아 적절하지 않다.
요약
- 선착순 요청에 따라 Queue 를 구현하는 과정은 간단하다.
- 발급 수량 검증 과정이 까다롭다.
SET
- 중복을 허용하지 않는다
- 순서를 보장하지 않는다.
선착순 조건 처리
1. 유저 요청이 들어옴
2. set에 추가 ex)SADD
- 순서를 알 수 없어 선착순 처리를 할 수 없다.
검증 조건 처리
1. 유저 요청이 들어옴
2. 발급 수량 조회 및 검증 ex) SCARD
- set은 중복을 허용하지 않으므로 unique 한 요청의 수를 구분하기 쉬움
3. 중복 발급 검증 ex) SISMEMBER, SADD
- O(1) 로 탐색이 가능
요약
- 요청의 순서를 구분할 수 없음
- 발급 수량 검증은 간단하다.
SORTED SET
- 중복을 허용하지 않음
- 스코어를 사용해 정렬 가능
선착순 조건 처리
1. 유저의 요청이 들어옴
2. sorted set 에 요청을 추가 ex) ZADD
- score 를 time stamp 로 활용해 요청 순서로 정렬할 수 있음
검증 조건 처리
1. 유저 요청이 들어옴
2. 발급 수량 조회 및 검증 ex) ZCARD
- sorted set 은 중복을 허용하지 않아 unique 한 요청의 수를 구분하기 쉬움
3. 중복 발급 검증 ex) ZRANK, ZADD
- 추가가 되면 중복 X, 추가 되지 않으면 중복.
요약
- score를 활용해 요청의 순서를 구분할 수 있다
- O(logN) 복잡도가 소요
- 발급 수량 검증 간단
Sorted Set 을 활용한 구조
예상 시나리오
1. 유저의 요청이 들어옴( coupon_id, user_id)
2. 쿠폰 캐시를 통한 유효성 검증
- 쿠폰의 존재
- 쿠폰의 유효 기간
3. Sorted Set 에 요청 값을 추가 (ZADD score = time stamp)
4. 현재 요청의 순서 조회 (ZRANK) 및 발급 성공 여부 응답
5. 발급에 성공했다면 쿠폰 발급 Queue에 적재
SET을 활용한 구조
예상 시나리오
1. 유저의 요청이 들어옴( coupon_id, user_id)
2. 쿠폰 캐시를 통한 유효성 검증
- 쿠폰의 존재
- 쿠폰의 유효 기간
3. 중복 발급 요청 여부 확인 SISMEMBER
4.수량 조회 ( SCARD) 및 발급 가능 여부 검증
5. 요청 추가 (SADD)
6. 쿠폰 발급 Queue 에 적재
'JAVA > 프로젝트' 카테고리의 다른 글
쿠폰 선착순 발급 이벤트 -프로메테우스, 그라파나를 사용해 모니터링 환경 구축 (0) | 2024.12.09 |
---|---|
쿠폰 선착순 발급 이벤트 - redis 분산락 쿠폰 발급 문제점. (0) | 2024.12.05 |
쿠폰 선착순 발급 이벤트 - 동시성 이슈 해결. MySql lock (0) | 2024.11.30 |
쿠폰 선착순 발급 이벤트 - 동시성 이슈 해결 synchronized (1) | 2024.11.30 |
쿠폰 선착순 발급 이벤트 - locust 설정, docker-compose.yml 작성 (0) | 2024.11.28 |