Skip to content

Latest commit

 

History

History
65 lines (63 loc) · 5.07 KB

우아콘 2023 - 대규모 트랜잭션을 처리하는 배민 주문시스템 규모에 따른 진화.md

File metadata and controls

65 lines (63 loc) · 5.07 KB

우아콘 2023 - 대규모 트랜잭션을 처리하는 배민 주문시스템 규모에 따른 진화

대규모 트랜잭션을 처리하는 배민 주문시스템 규모에 따른 진화 #우아콘2023 #우아한형제들

1. 배달의 민족 주문 시스템

  • 배민의 주문시스템 개발팀 : 장바구니 → 주문하기 → 주문내역
  • 배민 주문 시스템의 특징 :
    • 12시, 18:30 점심/저녁식사 특정 시간대에 트래픽이 몰림
    • 커머스 + 푸드 도메인
    1. MSA 구조 : 가게, 메뉴, 주문, 결제, 배달 등의 수많은 시스템이 통신하고 있음
    2. 대용량 데이터 : 일 평균 300만건의 주문
    3. 대규모 트랜잭션 : 특히 식사시간대 순간적으로 더 많은 트랜잭션
    4. 여러 시스템과 연계 : 이벤트 기반으로 다른 시스템과 통신

2. 성장하는 배민 주문 시스템

  • 매년 주문수가 가파르게 증가
  • 여러 성장통들
  • 1. 단일 장애 포인트
    • 증앙 집중 DB의 장애 → 전체 시스템으로 전파
    • ASIS 아키텍처 : 주문 시스템 → 루비 (단일 포인트) → 주문 중계, 가게, .. 등
    • 탈 루비 프로젝트 : 각 시스템에 맞는 도메인을 모델링 후 디비 분리 → MQ를 이용한 이벤트 기반 통신 & 시스템 간 영향도 분리
  • 2. 대용량 데이터
    • 대용량 데이터 → DBMS 조인으로 조회 성능 하락
    • 주문 요청 이벤트 → 주문 API → 주문 DB
    •                    → 주문 MQ → 주문 이벤트 처리 & 외부 시스템
      
    • 주문 조회 쿼리 → 주문 인터널 API → 주문 DB
    • 주문 RDBMS에서 주문 저장과 조회가 함께 일어나고 이씀
    • 주문내역을 보여주기 위해서는 아주 결제,주문,메뉴,배달 등 여러 테이블을 함께 조회해야 함 → 조회성능 문제
    • 역정규화 → MongoDB NoSQL 단일 Document
    • → 어떻게 동기화??
    • 주문 도메인 생명 주기 : 주문 생성 → 주문 접수 → 배달완료 / 주문취소 → 이 사이에서만 데이터 변경이 일어남.
    • CQRS 패턴 적용
    • → 주문 API에서는 이전처럼 정규화된 RDMBS에 주문 내역 저장 & 이벤트를 수신한 주문한 주문 이벤트 처리기에서 몽고DB에 저장
    • 커멘드 모델과 조회 모델을 분리 & 조회 모델 역정규화
  • 3. 대규모 트랜잭션
  • 주문 DB의 분당 쓰기 처리량의 한계치에 도달함.
  • 주문 DB 구성
    • 주문 API → 주문RW Primary → 스펙 업으로만 대응 가능
    • 주문 인터널 API → 주문 DB RO Replica → ScaleOut으로 대응 가능
  • 샤드 클러스터 구성 : RW DB 를 스케일 아웃하자!
  • → 그러나 AWS 오로라는 샤딩을 지원하지 않음
  • 어플리케이션 샤딩을 지원하자!
      1. 어떤 샤드에 저장할지 고민하는 샤딩 전략에 대한 고민
      2. 여러 샤드에 저장된 데이터를 애그리게이트하는 방법에 대한 고민
  • 어떤 샤딩전략을 사용할까?
      1. Key based Sharding : Shard Key를 이용하여 데이터 소스를 결정
      • 구현이 간단하고 데이터를 골고루 분배할 수 있으나 장비를 추가/제거하기 어려움 (재배치 필요)
      1. Range based Sharding : 값의 범위 기반으로 데이터 분산
      • Range로 구현하기 때문에 구현이 간단하지만, 특정 샤드에 데이터가 몰리는 핫스팟 발생 가능성
      1. Directory based Sharding : 샤드가 어떤 데이터를 가질지 룩업 테이블 구성
      • Key Based와 비슷하지만 인덱스 같은 룩업 테이블을 가지고 있음.
      • 동적으로 샤드 추가하는데 유리하지만 단일 장애포인트가 될 수 있는 문제점
  • 기존 주문 시스템의 특징은?
    • 주문이 정상 동작하지 않으면 배민 전체의 장애라고 인지하는 니쁜 경험을 줄 수 있음 → 단일 장애 포인트는 피하자
    • 동적 주문데이터는 최대 30일만 저장한다 (배달 특성상 하루안에 생명주기가 끗) → 샤드 추가 이후 30일이 지나면 데이터는 다시 균등하게 분배될 것
    • 주문번호를 샤드키로 사용해 Key Based Sharding 전략 사용
  • 어플리케이션 구현은 어떻게?
    • AOP, AbstractRoutingDataSource 이용해서 구현
  • 4. 다건 조회시 애그리게이트
    • 다건 조회는 몽고DB를 활용
    • 샤딩으로 인해 증가하는 트랜잭션을 스케일아웃으로 대응 가능해짐
  • 4. 복잡한 이벤트 아키텍처
  • 규칙성 없는 무분별한 이벤트 발생
  • 주문 도메인 로직 (주문 라이프 사이클 내) & 기타 서비스로직 (알림 발송, 영수증 등)으로 분리
  • 주문 시스템 이벤트 아키텍쳐 : 주문 도메인 로직 → Spring event로 발행 → OrderOpenPostProcessService, OrderAcceptPostPorcessService등이 구독해서 로직 수행
  • 시스템 관점으로 바라본 아키텍쳐 : 스프링 애플리케이션 이벤트는 로직을 수행하는 주체를 파악하기 어려워짐