주문이 몰릴 때 재고부터 살펴본 이유
커머스 플랫폼을 맡고 나서 먼저 이해해야 했던 것 중 하나가 재고 처리였습니다. 같은 상품을 구매하려는 요청이 한꺼번에 들어오면, 여러 서버가 결국 같은 재고 데이터를 조회하고 수정하게 됩니다. 서버를 늘리는 것만으로 해결하기 어려운 지점이었습니다.

재고 조회와 차감의 차이
상품을 조회하는 요청과 재고를 차감하는 요청은 부하의 성격이 다릅니다. 조회는 데이터를 읽는 경로를 분산할 수 있지만, 차감은 같은 재고를 여러 주문에 중복으로 배정하지 않도록 처리해야 합니다.
당시에는 재고 차감 과정의 DB 트랜잭션 경쟁이 부담이었습니다. 인기 상품에 요청이 집중되면 같은 데이터를 수정하려는 트랜잭션이 기다리게 됐고, 범위 잠금이 겹치는 구간도 함께 살펴봐야 했습니다. 응답이 느리다는 사실만으로는 어떤 요청이 무엇을 기다리는지 알기 어려웠습니다.
SKU와 출고 위치 확인
처음에는 SKU와 재고 데이터의 관계부터 확인했습니다. 상품의 재고가 어느 단위로 관리되는지 알아야 요청이 몰리는 지점도 찾을 수 있습니다. 출고 위치를 나타내는 fulfillment location이 재고와 어떻게 연결되는지도 함께 봤습니다.
그다음에는 조회와 차감이 발생하는 순서를 따라갔습니다. 상품 화면에서 보여주는 재고와 주문 과정에서 확인하는 재고가 어떤 경로를 사용하는지, 실제 차감은 언제 일어나는지 확인했습니다. 테이블 구조와 요청 과정을 같이 봐야 읽기 부하와 쓰기 경쟁을 나눠 생각할 수 있었습니다.
읽기 분산과 차감 처리 개선
당시 고도화 계획에는 읽기 전용 DB, 큐, 캐시와 NoSQL을 활용하는 방안이 있었습니다. 각각 해결하려는 문제가 달랐습니다.
| 방안 | 줄이려는 부하 |
|---|---|
| 읽기 전용 DB로 조회 분산 | 쓰기 DB에 함께 몰리는 읽기 요청 |
| 큐를 통한 차감 처리 | 같은 재고를 동시에 수정하려는 요청 |
| 캐시 등 조회 저장소 활용 | 반복 조회로 발생하는 RDB 부하 |
실제로 적용해 효과를 느낀 것은 ProxySQL을 통한 읽기·쓰기 분리였습니다. 읽기 요청을 분산하면서 이전보다 트래픽을 견디는 데 도움이 됐습니다. 다만 조회를 분리해도 같은 재고를 차감하는 요청끼리의 경쟁은 남습니다.
큐를 이용한 차감 처리 개선은 필요성을 느꼈지만 도입까지 이어지지는 못했습니다. 당시 검토했던 선택지와 실제 반영한 변경을 구분해서 기억할 필요가 있습니다.
다음 글에서는 재고 외에 관리자 조회와 배치까지 함께 영향을 받았던 대량 트래픽 상황의 병목을 다룹니다.