선착순 쿠폰 발급 시스템을 만들면서 가장 중요한 조건은 “한 유저가 하나의 쿠폰만 발급받을 수 있도록 보장”하는 것이었다. 즉, 중복 발급을 막고 동시에 만료 시간(유효기간)도 관리해야 했다. 전통적인 방식이라면 쿠폰 발급 내역을 DB에서 user_id
, coupon_id
로 조회하고 처리하겠지만 이 방식은 다음과 같은 문제를 가진다.
이를 해결하기 위해 Redis에 userId
와 couponId
를 조합한 키를 만들고 TTL을 설정하는 방식으로 개선했다.
Key: coupon:{couponId}:user:{userId} -> 예: coupon:1:user:42
Value: 1 (혹은 발급 timestamp)
TTL: 쿠폰 유효 시간만큼 설정 (예: 1시간, 3일 등)
유저 42번이 1번 쿠폰을 이미 발급받았음을 의미한다.
쿠폰 발급 시도 시 Redis에서 coupon:{couponId}:user:{userId}
키 존재 여부를 먼저 확인한다.
키가 없으면
키가 이미 존재하면 중복 발급으로 판단하여 차단 한다.
userId
, couponId
를 key로 조합함으로써 빠른 존재 체크가 가능이 구조는 일반적인 정규화된 RDBMS 구조에서는 바로 떠올리기 어려운 방식이지만 Redis의 특성을 적극 활용한 역정규화 전략으로 볼 수 있다. 처음엔 key가 길어지는 것이 비효율적일까 고민했지만 성능 테스트 결과에서는 오히려 훨씬 빠르고 안정적인 동작을 보여줬다. 역정규화는 단순히 데이터를 중복 저장하는 게 아니라 특정 요구사항에 최적화된 형태로 데이터를 재배치하는 것이라는 점을 실전에서 체감할 수 있었다.