You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Redis에 메뉴의 재고가 캐싱되어 있지 않으면, 메뉴 ID에 분산락을 걸고 메뉴의 재고를 캐싱한다.
분산락을 거는 이유: 주문하기 API에서 Redis에 재고를 최신화하는 과정에서, 재고 정합성 불일치가 발생할 수 있기 때문
분산락이 이미 걸려있으면, 메뉴의 재고가 캐싱되어 있는지 다시 확인한다.
분산락이 걸려있다는 것은 카트담기API 혹은 주문하기API에서 메뉴 재고를 최신화하고 있다는 의미이므로.
시스템 설계
트랜잭션을 반드시 걸어야하는 이유
재고 접근 시나리오
sequenceDiagram
participant C as 클라이언트
participant CS as 장바구니서비스
participant CR as 장바구니저장소
participant MR as 메뉴저장소
participant R as 레디스
participant DB as 관계형DB
participant LS as 잠금서비스
C->>CS: addMenu(AddCartCommand)
CS->>CR: getCart(customerId)
CR-->>CS: 고객 장바구니 반환
CS->>DB: findByIdWithStore(menuId)
alt 메뉴 찾음
DB-->>CS: 메뉴 반환
loop 메뉴ID 확인 및 저장
CS->>R: 메뉴ID 존재 여부 확인
alt {메뉴ID:재고}가 레디스에 존재
R-->>CS: 존재 확인 + RDB는 과거 정보이고 Redis 는 최신 정보이기 때문에 RDB에서 반환받은 재고를 Redis 재고로 업데이트
else {메뉴ID:재고}가 레디스에 없음
CS->>LS: 락 확인(menuId)
alt 락이 걸려있지 않음
LS-->>CS: 락 없음
CS->>LS: 락 설정(menuId)
CS->>R: 메뉴 재고 정보 저장
CS->>LS: 락 해제(menuId)
else 락이 걸려있음
LS-->>CS: 락 존재
Note over CS: 짧은 대기 후 [메뉴ID 확인 및 저장]루프 처음으로 돌아가 재시도
end
end
end
CS->>CS: 장바구니에 메뉴 추가
CS->>CR: 장바구니 저장
CR-->>CS: 저장 완료
CS-->>C: 성공 응답
else 메뉴 없음
CS->>C: MenuNotFoundException 발생
end
Loading
2. 재고 수량 Redis-RDB 정합성 문제
sequenceDiagram
participant C as 클라이언트
participant CS as 장바구니서비스
participant R as 레디스
participant DB as 관계형DB
participant LS as 잠금서비스
C->>CS: 장바구니 아이템 처리 요청
loop 각 장바구니 아이템에 대해
loop 메뉴ID 확인 및 처리
CS->>R: {메뉴ID:재고} 존재 여부 확인
alt {메뉴ID:재고}가 레디스에 존재
CS->>R: 원자적으로 재고 감소
alt 재고 < 0
CS->>R: 롤백 (재고 증가)
CS->>C: 재고부족 예외 발생
Note over CS: 재고 부족 이 발생하면 기존 재고 감소를 기록한 리스트를 돌면서 다시 재고를 증가시켜주는 로직을 추가해야함
else 재고 >= 0
CS->>CS: 재고 수정 로그 리스트에 {메뉴ID:수문수량} 기록
end
else {메뉴ID: 재고}가 레디스에 없음
CS->>LS: 락 확인(menuId)
alt 락이 걸려있지 않음
LS-->>CS: 락 없음
CS->>LS: 락 설정(menuId)
CS->>DB: 재고 조회
DB-->>CS: 재고 반환
CS->>CS: 재고 감소
alt 재고 < 0
CS->>CS: (재고 증가)
CS->>R: 재고 정보 저장
CS->>C: 재고부족 예외 발생
Note over CS: 재고 부족 이 발생하면 기존 재고 감소를 기록한 리스트를 돌면서 다시 재고를 증가시켜주는 로직을 추가해야함
else 재고 >= 0
CS->>R: 재고 정보 저장
CS->>CS: 재고 수정 로그 리스트에 {메뉴ID:수문수량} 기록
end
CS->>LS: 락 해제(menuId)
else 락이 걸려있음
LS-->>CS: 락 존재
Note over CS: 짧은 대기 후 [메뉴ID 확인 및 처리]루프 처음으로 돌아가 재시도
end
end
end
Note over CS: [주문 성공 시]<br/> RDS 동기화 옵션 고려:<br/>1. 비동기 업데이트<br/>2. 예약된 업데이트
end
CS->>C: 결과 반환
Loading
비동기 where update 로 진행하고 나중에 배치 고려
재고 부족 이 발생하면 기존 재고 감소를 기록한 리스트를 돌면서 다시 재고를 증가시켜주는 로직을 추가해야함…
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
일시: 24년 08월 24일 14시
참가자: 김준기, 김현수
1. 재고 수량 Redis 캐싱 시점
방안1. 서버 로드 시점에, 모든 메뉴의 재고 수량을 웜업
단점: 불필요한 Redis 메모리 사용률 증가
방안2. 서버 로드 시점에, 인기 가게 메뉴의 재고 수량만 웜업
단점: 성능 테스트가 어려움, 서비스 운영 시점에 고려해볼만 함
방안3. 카트에 메뉴를 넣는 시점에 재고 수량을 캐싱
2. 재고 수량 Redis-RDB 정합성 문제
비동기 where update 로 진행하고 나중에 배치 고려
재고 부족 이 발생하면 기존 재고 감소를 기록한 리스트를 돌면서 다시 재고를 증가시켜주는 로직을 추가해야함…
Beta Was this translation helpful? Give feedback.
All reactions