🔄 실시간 재고 동기화 (Kafka + InventoryHub)
OMS·WMS·마켓플레이스·POS 채널 통합 동기화 · 가상 재고 풀(VIP) · Oversell 0건 · 김지훈 수석연구원
다채널(쇼핑몰·마켓·POS) 재고 운영은 본질적으로 race condition이다. WMS에서 1개 차감되는 동시에 POS가 1개를 팔고, 마켓플레이스가 1개를 reserve하면 동일 SKU가 동시에 3번 commit되어 Oversell(초과 판매)이 발생한다. 폴링(N분 주기 스냅샷) 방식으로는 이 race를 막을 수 없다.
RT-O5는 이 문제를 해결하기 위해 4개 Kafka topic으로 모든 mutation을 단일 스트림으로 모은 뒤, 중앙 InventoryHub가 ATP(Available To Promise)를 계산해 모든 채널에 broadcast한다. Idempotent consumer + exactly-once semantics + per-SKU partitioning으로 순서를 보존하고, 가상 재고 풀(Virtual Inventory Pool, VIP)로 거점·채널별 가용 재고를 단일 풀로 추상화한다. 3월 4주차 기준 Oversell 0건, p95 sync latency 38ms, 채널 재고 불일치 0.04%를 달성했다.
WMS / POS / OMS / 반품 시스템에서 mutation 이벤트 발행 (각자 topic). 발행자는 InventoryHub 존재를 알 필요 없음.
SKU 기반 partitioning · ordering 보장 · idempotent producer. 동일 SKU는 항상 같은 partition.
Flink/Faust streaming consumer · ATP 계산 · 가상 재고 풀(VIP) 갱신. exactly-once 처리.
RocksDB / Redis 상태 저장 · 30일 TTL · compaction · key=SKU, value=ATP snapshot.
모든 채널 SDK / API에 실시간 가용 재고 푸시 (WebSocket / Webhook). p95 38ms.
# Kafka 기반 이벤트 드리븐 재고 동기화 TOPICS = [ "inventory.wms.updated", # WMS 재고 변동 "inventory.pos.sold", # POS 판매 "inventory.order.reserved", # OMS 예약 "inventory.order.released", # 주문 취소/반품 ] # 모든 채널 재고 이벤트를 중앙 InventoryHub로 집계 # InventoryHub -> 전 채널에 최신 가용 재고 broadcast def compute_atp(sku): snap = state_store.get(sku) return snap.on_hand - snap.reserved - snap.allocated + snap.in_transit
4개 topic은 모두 partition 16(SKU hash 기반)으로 운영하며, idempotent producer(enable.idempotence=true) + transactional consumer로 exactly-once를 보장한다. broker는 3대 replication factor 3으로 durability 확보.
inventory.wms.updated · WMS의 입고/출고/이동/실사 결과로 OnHand 갱신. 가장 큰 변동량 차지inventory.pos.sold · 매장 POS 판매로 OnHand 즉시 차감. 초당 수백 건 burst 발생inventory.order.reserved · 온라인 주문 reserve로 Reserved 증가. 결제 완료 시 Allocated 전환inventory.order.released · 취소/반품으로 Reserved 해제. 가장 빈도 낮음예) SKU-A의 OnHand=10, Reserved=3, Allocated=2, InTransit=5라면 ATP = 10 − 3 − 2 + 5 = 10이다. 이 시점 5개 채널이 동시에 11개를 commit하려 하면 Oversell_risk = 11 − 10 = 1로 1건 reject되고 InventoryHub가 즉시 모든 채널에 ATP=0으로 broadcast한다.
| 채널 | 평균 mutation rate | sync p95 | 재고 정확도 | 주요 이벤트 |
|---|---|---|---|---|
| WMS | 230 ops/s | 22ms | 99.99% | 입고/출고/이동/실사 |
| POS | 180 ops/s | 31ms | 99.97% | 매장 판매 즉시 차감 |
| 마켓플레이스 | 480 ops/s | 38ms | 99.96% | 쿠팡·네이버·11번가 reserve burst |
| B2B EDI | 80 ops/s | 64ms | 99.94% | 대량 주문(EDI 850) batch |
마켓플레이스가 가장 큰 mutation rate(480 ops/s)를 차지하며 burst가 잦아 partition 추가가 중요하다. B2B EDI는 batch성이라 latency가 64ms로 다소 높으나 정확도는 99.94%로 안정. WMS는 가장 빠른 22ms로 동작하며 재고 정확도 99.99%로 baseline 역할을 한다.
[1] 김지훈, "실시간 재고 동기화 (Kafka + InventoryHub)", IntraLogis 사내 보고서, 2026.03
[2] Apache Kafka, Apache Kafka 공식 문서, 2025
[3] Confluent, "Streaming ATP Patterns", Confluent Blog, 2024
[4] Apache Flink, Apache Flink Stateful Streaming Documentation, 2025
[5] Kleppmann, M. "Designing Data-Intensive Applications", O'Reilly, 2017
[6] Facebook, RocksDB 공식 문서, 2025
[7] 박소연 · 김지훈, WMS-OMS 통합 협력 보고서, IntraLogis 사내, 2026.02