이번 과제는 단순 기능 구현이 아니라 다수 서버 환경에서 안정적으로 동작하는 시스템 설계가 핵심이라고 판단했다.
그래서 다음 3가지를 중심으로 구조를 설계했다.
전체 흐름은 다음과 같이 구성했다.
포인트는 동일 사용자에 대해 동시에 수정될 가능성이 높기 때문에 userId 기준 Redis 분산 락을 적용했다.
또한 락과 트랜잭션을 분리하여 DB 반영 완료 후 락이 해제되도록 구조를 설계했다.
-> 결과적으로 다중 서버 환경에서도 포인트 데이터 충돌을 방지할 수 있다.
주문/결제 API에서는 다음 작업을 하나의 트랜잭션으로 묶었다.
이렇게 설계한 이유는:
또한 Kafka 전송은 트랜잭션 외부에서 처리하기 위해 Outbox 패턴을 적용했다.
-> DB와 메시지 전송 간 불일치를 최소화하고, 재처리가 가능한 구조를 확보했다.
주문 완료 후 이벤트를 Kafka로 전송하고, Consumer가 다음 작업을 수행하도록 분리했다.
-> 이후 통계, 알림, 추천 시스템 등으로 쉽게 확장 가능
인기 메뉴는 최근 7일 기준으로 집계해야 하므로 날짜별 ZSet 구조로 설계했다.
조회 시 최근 7일 데이터를 합산하여 Top3를 계산한다.
-> 빠른 조회 성능 + 기간 기반 집계 가능
-> 트래픽 증가 시 병목 분리 가능
| 관점 | 선택 | 이유 |
|---|---|---|
| 동시성 | Redis 분산 락 | 다중 서버 환경에서도 사용자 단위 동기화 가능 |
| 데이터 일관성 | 트랜잭션 + Outbox | 부분 성공 방지 및 이벤트 유실 최소화 |
| 확장성 | Kafka + Consumer | 기능 확장 시 구조 변경 없이 대응 가능 |
| 성능 | Redis 캐시 & ZSet | 조회 속도 향상 및 실시간 집계 |
이번 설계는 단순 기능 구현이 아니라 안정성과 확장성을 고려한 구조 설계에 초점을 맞췄다.
-> 결국 이 시스템은 “문제가 생기지 않도록 미리 구조를 설계한 시스템”이라고 정리할 수 있다.