Tiny Star

프로젝트/쿠폰

[쿠폰] Redis 선착순 쿠폰 시스템

흰둥아 2025. 4. 28. 11:34

Redis를 사용하여 선착순 쿠폰 시스템을 만들어보기로 했다.

쿠폰에 초점이 맞춰진만큼 로그인 기능 등은 안넣고 오로지 쿠폰 발급만 구현하려고 한다.

 


 

🎯 시스템 구성 목표

  • 로그인 없이 (단, userId는 요청에 포함)
  • 선착순 쿠폰 발급
  • 쿠폰 재고는 Redis로 관리
  • 쿠폰 발급 결과만 DB에 저장
  • 빠른 응답 최우선

 

 

✅ API 설계

구분 내용
Method POST
URL /api/coupons/issue
요청 Body { "userId": "string", "couponId": "string" }
응답 성공: { "success": true, "message": "쿠폰 발급 성공" }
실패: { "success": false, "message": "쿠폰 소진" }

 

 

✅ ERD 설계

[Coupon] (쿠폰 종류 관리 테이블)
- coupon_id (PK) : bigint (auto increment)
- name : varchar
- total_quantity : int
- created_at : timestamp
- updated_at : timestamp

[CouponIssue] (쿠폰 발급 이력 테이블)
- id (PK) : bigint (auto increment)
- user_id : varchar
- coupon_id (FK) : bigint
- issued_at : timestamp

 

  • Coupon 테이블은 "어떤 쿠폰이 몇 장 있는지" 정의
  • CouponIssue 테이블은 "누가 어떤 쿠폰을 언제 발급받았는지" 기록

 

 

✅ Redis 구조

키 이름 예시 타입 설명
coupon:{couponId}:stock String (Integer) 쿠폰 잔여 수량 관리
coupon:1234:stock = 500 (500장 남음)

 

  • 발급할 때마다 DECR 명령어로 -1 감소
  • 0 이하면 발급 불가 처리

 

 

✅ 동작 흐름도

[Client]
    ↓ POST /api/coupons/issue
[Server]
    ↓
1. Redis 쿠폰 수량 조회 & 감소 (DECR)
2. 만약 수량 0 미만이면 실패 응답
3. 수량 0 이상이면 성공 응답
4. 발급 이력 DB에 저장 (CouponIssue)

 

 

 

✅ 1차 프로젝트 구성 요약

항목 기술/구성
백엔드 Spring Boot (Java)
DB MariaDB
In-memory 캐시 Redis
부하 테스트 도구 k6 + InfluxDB + Grafana
기본 구조 Redis로 수량관리, MariaDB로 발급이력 저장

 

 

 

📈 초기 개발/테스트 포인트

 

  • Race Condition 방지: Redis DECR는 원자 연산이므로 별도 락 필요 없음.
  • 초과 발급 방지: DECR 결과를 무조건 체크해야 함 (0 이하면 발급 실패)
  • 중복 발급 방지(추후): userId+couponId를 Redis에 임시 저장하면 강화 가능
  • DB 저장 실패 대비: 로그 남기고, 필요하면 재시도

 

 

 

 

top