TIL

2025.05.10 재고 트랙픽과 캐시 4

Gisungcu 2025. 5. 10. 14:04

 

이전에 재고를 레디스에서 관리함으로써 사용자에게 빠른 응답을 줄 수 있었습니다.

DB의 데이터가 재고 자원의 원천이기에 비동기로 최종적 일관성을 맞춰줍니다. 

 

최근 고민하던 구조를 복기하면서, 놓치고 있던 문제점들을 발견했습니다.

상품 재고는 단순히 product_id 단위로만 관리되지 않고, 유통기한, 창고 위치, 구매처 등 여러 메타 정보로 구분된 정보로 관리됩니다.

상품하나에 여러 개의 서로 다른 유통기한, 위치 재고가 존재할 수 있습니다.

유저는 이를 몰라도 요청할 수 있습니다. 그래야만 하고요.

위의 다이어그램으로는 유저의 요청은 수용할 수 있습니다.

 

하지만 어드민은 상품의 재고 중 일부를 폐기할 수 있습니다.

어드민의 요청은 유저의 요청처럼 선입선출로 재고 차감이 이뤄지는 것이 아닌 상품 id, 유통기한, 위치가 동일한 재고를 차감되어야 합니다.

 

이때 발생할 수 있는 문제가 있습니다.

재고의 모든 read, write는 레디스를 접근하도록 했습니다.

하지만 레디스 재고 key는 상품 id이기 때문에 허들이 존재합니다.

 

 

1. sorted set 사용

레디스 sorted set을 활용하면 어떨까요?

  • key는 상품 id,
  • member는 유통기한:구매처:위치 문자열
  • (member를 여러 개 등록할 수 있습니다.)
  • score는 재고량

단점으로 score가 재고이기에 선입선출 구현, read write증가로 인해 레이턴시가 증가할 수 있습니다.

또 유저의 요청이 재고의 위치까지는 몰라도 되지만, 서버에서 시스템 복잡성이 올라가게 됩니다.  

 

 

2. key mapping 사용

상품 id:유통기한:구매처.. 문자열 key로 따로 등록하고 value에 재고를 등록합니다.

이 key들을 가지고 있는 keys라는 것을 등록해 조회하는 것입니다.

단점으로는 1번과 동일한 문제가 생길 수 있습니다.

 

 

뭔가 다 마음에 들지 않습니다만 마땅한 방법이 떠오르지 않는군요.

어드민의 재고 이동도 레디스를 통해 조작하는게 맞을까요?

 

다르게 생각해봅시다.

이제 상품 ID:유통기한:구매처:위치를 하나의 메타 데이터라고 정의하겠습니다.

 

이번에는 어드민 역시 사용자와 동일하게 레디스의 재고 차감 로직을 사용한다고 가정해봅니다.

재고 차감이 성공했을 때, 다음 두 가지 시나리오를 생각할 수 있습니다:

  • 요청한 메타 데이터와 동일한 재고를 차감했을 경우: 성공 케이스입니다.
  • 요청한 메타 데이터와 다른 재고가 차감된 경우: 메타 데이터는 다르지만 재고 차감은 완료된 상태 (불일치 케이스)

 

앞서 언급했듯이, 사용자(주문자)는 어떤 유통기한, 위치에서 재고가 나갔는지에는 관심이 없습니다.

사용자에게 중요한 것은 “상품 ID 단위의 재고가 차감되었는가” 뿐입니다.

그러나 어드민의 입장에서는 요청한 메타 데이터 단위의 재고 차감 여부가 중요합니다.

 

그렇기에 메타 데이터 불일치 케이스(다른 재고가 차감된 경우) 에 대해서는, 어드민이 요청한 메타 데이터와 실제 차감된 메타 데이터 간의 SWAP(교환) 로직을 통해 일관성을 복원하는 방법을 고려할 수 있습니다.

어드민 관점에서는 메타 데이터 일관성(요청한 메타 데이터 -> 실제 반영된 메타 데이터) 을 복원할 수 있습니다.

 

이건 어드민의 재고 차감의 경우의 로직이 될 것으로 생각됩니다.

 

복잡도가 올라가긴합니다.

하지만 이벤트의 분리와 메소드의 명시적 분리를 통해 관리한다면, 운영 및 유지보수는 할 수 있다고 생각합니다.

또 SWAP은 비동기로 빼도 됩니다.

 

근데 사용자가 보는 주문가능재고와 실질적인 재고 사이에는 판매자의 구매수락 완료등의 행위가 들어갈 수 있습니다.