Redis를 캐시로만 쓰지 않기 위해 구현한 대기열, 분산 락, Presence, 정합성 복구
Concert Booking의 queue/stock, Realtime Chat의 presence, TimeDeal의 캐시, PostgreSQL 기준 reconciliation을 한 문서로 연결합니다.
핵심 관점
Redis는 빠른 상태 조회와 경합 완화에는 강하지만, 장애 이후 무엇이 맞는 상태인지 설명해야 하는 순간에는 최종 기준 데이터가 되기 어렵습니다. 그래서 이 포트폴리오에서는 Redis를 캐시, 대기열, presence, reconciliation 대상으로 쓰되 최종 기준 데이터는 PostgreSQL과 도메인 DB에 둡니다.
이 글은 Redis를 많이 썼다는 주장이 아니라, Redis가 맡은 역할과 맡기지 않은 역할을 분리한 기록입니다. 수치가 있는 항목은 각 프로젝트의 evidence로 남기고, 운영 성능 주장은 별도로 하지 않습니다.
Concert Booking: 대기열과 좌석 경합
Concert Booking에서는 Redis가 대기열 토큰과 빠른 stock 조회를 돕지만, 좌석/예약의 최종 기준 데이터는 PostgreSQL Reservation / Seat 상태입니다. 동일 좌석 100개 동시 요청에서 success 1, fail 99, overselling 0을 기록한 것도 Redis 단독 결과가 아니라 transaction, seat lock, Idempotency-Key, Outbox를 함께 묶은 결과입니다.
서로 다른 좌석 50명 동시 예약에서는 pessimistic lock과 Redis distributed lock 모두 50/50 성공을 확인했습니다. 다만 이 결과도 운영 성능 주장이 아니라 로컬 시나리오에서 락 전략의 실패 양상을 비교한 evidence로만 둡니다.
Redis stock과 DB 상태가 어긋날 수 있다는 전제를 버리지 않았기 때문에 reconciliation은 Redis 값을 기준으로 DB를 고치는 방식이 아니라, PostgreSQL 기준으로 Redis 보조 상태를 복구하는 방향으로 설계했습니다.
Realtime Chat: presence는 최종 상태가 아니다
Realtime Chat에서 Redis presence는 지금 연결되어 있을 가능성이 높은 사용자를 빠르게 표현하는 ephemeral state입니다. heartbeat와 TTL이 어긋나면 실제 접속 상태와 다를 수 있으므로, 메시지 복구는 Redis presence가 아니라 Message DB와 reconnect sync API 기준으로 처리합니다.
WebSocket receiver matrix evidence도 presence 자체를 delivery completeness로 착각하지 않기 위해 분리했습니다. ACK, persisted message id, receiver delivery는 서로 다른 관찰 지점입니다.
TimeDeal과 AI Billing에서의 경계
TimeDeal Service에서는 Redis/Caffeine 캐시와 Resilience4j를 commerce resilience 관점으로 정리했습니다. 캐시는 응답 속도와 장애 전파 완화에 도움이 되지만, 가격·주문·재고의 최종 판정은 도메인 저장소와 트랜잭션 경계에서 설명되어야 합니다.
AI Usage Billing Gateway는 Redis 사례라기보다 같은 원칙의 반대편에 있는 기준점입니다. 과금의 최종 설명은 Usage Event, Invoice, Append-only Ledger, Audit Log가 담당하고, webhook 재전송이나 duplicate usage는 캐시로 숨길 문제가 아니라 idempotency와 ledger invariant로 드러내야 하는 입력입니다.
면접에서 설명할 문장
Redis는 빠른 판단을 돕는 도구로 쓰고, 장애 후 복구 기준은 도메인 DB와 ledger에 둡니다. 그래서 대기열, presence, cache, stock 같은 Redis 상태는 모두 유용하지만, 최종 기준 데이터와 reconciliation 방향을 먼저 정해두지 않으면 장애 상황에서 무엇을 고쳐야 하는지 설명하기 어렵습니다.