Search

[Applicaion]10.비동기 구조: Redis 서버 구조 설계

Publish Date
2024/11/15
Tags
Status
Done
1 more property
Context
Table of Content

기존 구조의 문제점

현재 구조

사용자 요청 → API 서버 → MySQL 처리(트랜잭션)

과정

1.
N명의 사용자가 API로 요청을 보낸다.
2.
API서버에서는 N개의 요청을 처리한다.
3.
N개의 쿠폰 발급 트랜잭션을 처리 한다.
쿠폰조회 (findCouponWithLock(couponId) )
쿠폰 발급 검증 및 수량증가(coupon.issue() , issuedQuantity++ )
쿠폰 발급 정보 저장 (saveCouponIssue(long couponId, long userId) )

문제점

사용자 요청을 직접 DB에서 처리하여 트래픽이 증가할 경우 DB 과부하 발생
API서버를 확장(scale-out)해도 트랜잭션 병목은 DB에서 발생하여 성능 한계에 도달

개선 구조: 1단계 - Redis추가

도입배경: MySQL 과부하

사용자 요청 → API 서버 → MySQL 처리 구조의 경우, 사용자 요청을 DB에서 직접 처리.
쿠폰 이벤트 진행 시 트래픽 증가로 인해 동시성문제와 MySQL 과부하 문제가 발생

변경사항

Redis 추가: API 서버와 MySQL 사이에 Redis를 추가하여 사용자 요청 처리 속도 개선.

과정

1.
N명의 사용자가 API로 쿠폰 발급 요청을 보낸다.
2.
쿠폰 요청 처리 서버에서는 쿠폰 발급 대상을 검증하여 사용자에게 {성공, 실패}여부를 응답해주며, Redis에 발급 대상을 전달한다.
3.
쿠폰 발급 성공 대상(couponId, userId)을 Redis에 저장한다.
4.
Redis에 쿠폰 발급 성공 대상을 스케줄링 방식으로 가져와 안정적으로 트랜잭션을 수행한다.

효과

MySQL에 직접적으로 부하를 주는 요청을 Redis에서 처리하여 병목 현상 해소
Redis를 추가하여 선착순 요청을 빠르게 처리하며 발급 성공한 사용자 정보를 저장한다.

개선구조: 2단계 - 기능 별 서버 분리

도입배경: API 서버의 부하

사용자 요청 처리와 트랜잭션을 함께 수행하여 API 서버에서 부하 발생.

변경사항

API서버와 발급서버를 분리
API서버(coupon-api)는 사용자의 요청 중 발급 성공 대상을 Redis Queue에 저장
발급서버(coupon-consumer)는 Redis Queue에서 발급 성공 대상을 DB에 트랜잭션 수행

과정

1.
N명의 사용자가 API로 요청을 보낸다.
2.
coupon-api서버: 사용자 요청 트래픽 처리(사용자요청) API서버(conpon-api)에서는 N개의 사용자 요청에 대해 발급 검증한다.
사용자에게 발급 {성공/실패} 응답
검증 성공하면 Redis Queue에 발급성공대상(coupon_id, user_id) 을 저장
3.
coupon-consumer서버: 쿠폰 발급 트랜잭션 처리(MySQL 발급 처리) 쿠폰 발급 처리 서버(coupon-consumer)에서는 스케줄링을 통해 Redis Queue의 발급성공대상(couponId ,userId)을 조회(Pull)하여 MySQL로 트랜잭션 수행 및 발급 처리

효과

사용자 요청 트래픽 처리와 쿠폰 발급 트랜잭션을 완전 분리하였다.
Redis : 사용자의 요청 트래픽 처리
MySQL : 쿠폰 발급 트랜잭션 처리
Redis Queue로 안정적인 트랜잭션 처리 및 MySQL의 트래픽 부담 감소
비동기 구조를 통해서 얻게 되는 이점:
1.사용자에게 즉각적인 응답을 제공하며
2.데이터베이스의 부하를 줄이고 처리 효율성을 높여 병목 현상을 완화 할 수 있다.
Search
Main PageCategoryTagskkogggokkAbout MeContact