시스템 아키텍트시스템 아키텍트

전 세계적으로 분산된 이벤트 소스 재고 관리 백본을 구축하여 플래시 세일 트래픽 쓰나미 동안 이질적인 창고 관리 시스템 간의 실시간 재고 할당을 조정하고, 분산 잠금 병목 현상 없이 과도 판매를 방지하기 위한 엄격한 직렬성을 보장하며, 보상 트랜잭션 패턴을 통해 기존 ERP 통합과의 최종 일관성 드리프트를 조정합니다.

Hintsage AI 어시스턴트로 면접 통과

질문에 대한 답변

역사: 전통적인 전자상거래 플랫폼은 낙관적인 잠금을 사용하여 모놀리식 RDBMS 인스턴스에 의존하였고, 초당 100,000명 이상의 동시 결제가 몰리는 플래시 세일 부하에서 붕괴되었습니다. 업계는 읽기 및 쓰기 경로를 분리하기 위해 CQRS이벤트 소싱 패턴으로 전환했지만, 이는 다양한 지연 특성을 가진 분산 WMS 및 레거시 ERP 사일로 전반에 걸쳐 재고 정확성을 유지하는 데 복잡성을 도입했습니다.

문제: 핵심 도전 과제는 네트워크 파편화 동안 CAP 정리에 대한 제약을 충족하면서 과도 판매를 방지하는 것—엄격한 비즈니스 불변입니다. RedLock과 같은 분산 잠금 메커니즘은 지연과 가용성 위험을 도입하며, 순전히 최종 일관성 모델은 허상 재고 판매의 위험이 있습니다. 또한, 레거시 SOAP/XML 기반 WMS 시스템과의 이질적인 통합 지점은 임피던스 불일치 및 시간 초과 연쇄를 일으켜 원자 트랜잭션 경계를 복잡하게 만듭니다.

솔루션: 재고 델타의 진실의 원천으로 이벤트 저장소(예: Apache Kafka 또는 EventStoreDB)를 구현하고, 전역 잠금 없이 인과적 순서를 설정하기 위해 벡터 클락을 사용한 낙관적 동시성 제어를 적용합니다. Temporal 또는 Camunda를 사용하여 크로스 WMS 트랜잭션을 관리하는 Saga 오케스트레이션을 사용하고, 여기서 지역 예약은 즉시 이벤트 저장소에 커밋되어 WMS의 비동기 승인이 최종 할당 또는 보상 해제를 촉발합니다. 읽기 확장을 위해 Redis 또는 ElasticsearchCDC를 통해 CQRS를 배포하여 50ms 미만의 읽기 지연을 보장하고, 예약 TTL로 완화되는 임시 신선도 수용합니다.

실생활의 상황

블랙 프라이데이 2022 준비 중, 글로벌 패션 소매업체는 50,000명의 동시 사용자가 제한된 에디션 스니커즈 출시를 목표로 할 때 치명적인 데이터베이스 초과 지연을 경험했습니다. 그들의 기존 MySQL 마스터-슬레이브 토폴로지는 핫 재고 행에서 심각한 쓰기 경합으로 12초 체크아웃 지연과 기본 및 읽기 복제 간의 복제 지연으로 인한 300건의 과도 판매 사건을 초래했습니다. 비즈니스는 판매 가능한 단위가 물리적 창고 재고를 초과하지 않도록 하면서 플래시 세일 트래픽 쓰나미를 흡수할 수 있는 솔루션을 요구했습니다.

엔지니어링 팀은 먼저 Redis RedLock 알고리즘을 세 개의 가용성 영역에 구현하여 재고 감소 동안 분산 상호 배제를 시행할 것을 제안했습니다. 이 접근 방식은 팀이 친숙한 강력한 일관성 보증과 기존 세션 관리에 이미 사용되고 있는 Redis 클러스터와의 간단한 통합의 이점을 제공했습니다. 그러나 주요 단점은 가용성 영역 실패 중 500ms를 초과하는 수용할 수 없는 지연 스파이크와 잠금 안전 속성을 무효화할 수 있는 시계 불일치의 이론적 위험이 포함되어 있어 가장 중요한 수익 창출 기간 동안 재고 할당이 교착 상태에 빠질 수 있다는 점이었습니다.

대안 전략은 SKU 범위에 따라 데이터베이스를 수평으로 샤딩하고 지역 PostgreSQL 인스턴스 전반에 걸쳐 ACID 보증을 유지하기 위해 2단계 커밋 프로토콜을 사용하는 것이 었습니다. 이 솔루션은 복잡한 최종 일관성 패턴 없이 강력한 일관성과 즉각적인 재고 정확성의 이점을 제공하여 전통적인 트랜잭션 사고방식에 적합했습니다. 그러나 단점은 실행 가능성이 있는 블로킹 성격으로, 코디네이터 실패로 인해 데이터베이스 잠금이 무기한 유지될 수 있고, 프로토콜의 메시지 복잡성으로 인해 트래픽 피크 동안 네트워크 포화가 발생하여 24/7 글로벌 상거래에 필요한 가용성 요구 사항을 근본적으로 위반한다는 것이었습니다.

최종 후보 아키텍처는 Apache KafkaSaga 오케스트레이션을 활용한 이벤트 소싱을 수용하여 보상 트랜잭션을 통해 비즈니스 불변을 집행하면서 BASE 의미론을 수용했습니다. 장점으로는 파티셔너블 이벤트 스트림을 통한 고유한 수평 확장성, 사기 분석에 중요한 불변 감사 추적, 그리고 비 신속 이벤트 소비자와의 자연스러운 통합을 포함합니다. 주요 단점은 불변 데이터 패턴에 익숙하지 않은 개발자에게 가파른 학습 곡선과 새로운 읽기 모델 프로젝션을 위한 이벤트 스키마 진화 및 재생 전략 관리의 운영 복잡성입니다.

아키텍처 위원회는 플래시 세일이 본질적으로 즉각적인 일관성보다 가용성과 파편 허용을 우선시하며, 비즈니스 로직이 하드 데이터베이스 잠금보다 5분 TTL이 있는 임시 소프트 예약을 수용할 수 있기 때문에 이벤트 소싱 접근 방식을 선택했습니다. 잠금 대안과 달리 이 설계는 데이터 센터 간의 네트워크 파편화 동안 시스템이 계속 가용 상태를 유지하도록 허용하여 창고 확인에 지연이 발생하더라도 고객이 항상 구매를 시도할 수 있도록 보장했습니다. 또한 불변 이벤트 로그는 재무 팀이 제3자 물류 제공업체와의 불일치를 조정하는 데 필요한 감사 가능성을 제공했습니다.

구현에서는 지역 재고 집계 관리를 위해 Kafka Streams, SAP 및 사용자 정의 WMS 시스템 간의 사가 오케스트레이션을 위해 Temporal, 쿼리 최적화를 위해 Redis와 쓰기 스루 캐싱을 배포했습니다. 이후 사이버 먼데이 이벤트 동안 플랫폼은 120,000건의 동시 체크아웃을 처리하며 p99 지연을 80ms 이하로 유지하고 과도 판매 사건 없이 99.99%의 가용성을 유지하여 이전의 모놀리식 아키텍처에서는 치명적이었을 지역 출력 시뮬레이션 상황을 극복했습니다.

후보자들이 자주 놓치는 것

전역 잠금을 사용하지 않고 여러 Kafka 파티션에서 동시 예약을 처리할 때 허상 재고를 어떻게 방지합니까?

허상 재고는 동시 명령이 서로 다른 파티션에서 오래된 재고 수준을 읽고 실제 가용성을 초과하는 예약을 모두 커밋할 때 발생합니다. 전역 잠금 없이 이를 방지하기 위해 이벤트 저장소 내에서 버전 번호를 사용한 낙관적 동시성 제어를 구현합니다. 각 재고 집계는 단조 카운터를 유지하고, 명령에는 예상 버전이 포함되며, 버전 불일치 시 저장소가 추가를 거부하여 클라이언트가 재시도하도록 강제합니다. 또한 특정 파티션에 SKU를 해싱하여 파티션 친화성을 보장하고, 각 집계당 단일 작성기 의미론을 유지하여 교차 파티션 조정을 완전히 제거합니다.

로컬 이벤트 저장소가 이미 재고 감소를 커밋한 후 레거시 WMS SOAP 엔드포인트의 시간 초과 시 보상 거래 전략은 무엇입니까?

이 시나리오는 부분 실패를 나타내며, 로컬 상태가 외부 현실과 분리되어 Saga 패턴으로 역방향 복구가 필요합니다. WMS 어댑터가 시간 초과에 직면하면 사가 오케스트레이터에 시간 초과 이벤트를 게시하고, 이후 Stock_Released 이벤트를 추가하여 재고를 사용 가능한 풀로 반환하면서 재시도 시 이중 할당을 방지하기 위해 Idempotency 키를 유지합니다. 중요하게도, 원래의 감소 이벤트를 삭제하지 마십시오; 대신 보상 이벤트를 추가하여 트랜잭션 시도의 전체 시간적 이력을 유지합니다.

불일치하는 재고 수치를 고객에게 노출하지 않고 이벤트 재생 및 읽기 모델 재구성을 어떻게 처리합니까?

이벤트를 재생하여 CQRS 읽기 모델을 재구성하는 것은 프로젝션이 쿼리가 실행되는 동안 점진적으로 업데이트되면 일시적으로 잘못된 재고 수준을 노출할 위험이 있습니다. 이 솔루션은 읽기 모델에 대해 블루-그린 배포를 사용합니다: 기존 인스턴스가 트래픽을 제공하는 동안 이벤트 로그에서 오프셋 제로부터 소비하는 쉐도우 프로젝션을 생성하고, 쉐도가 따라잡으면 원자적으로 라우팅을 전환합니다. 추가로, 이벤트 재생 시간을 줄이기 위해 Kafka 로그 압축 및 정기적인 S3 스냅샷을 활용하여 새로운 프로젝션이 재구성하는 동안 잠재적인 불일치의 창을 최소화합니다.