우아콘 2023, 우아한 형제들 세션 정리 #
대규모 트랜잭션을 처리하는 배민 주문시스템 규모에 따른 진화 #
성장통들 #
- 개선 대상 리스트
- 단일 장애 포인트
- 대용량 데이터
- 대규모 트랜잭션
- 복잡한 이벤트 아키텍처
단일 장애 포인트 #
-
루비라 불리는 중앙 집중 저장소에 모든 시스템이 의존
-
중앙 저장소의 부하 발생
해결 #
-
중앙 저장소 -> 각 시스템을 분리하는 프로젝트 진행
-
시스템 간 통신은 Message Queue 기반으로 통신
-
특정 시스템의 장애는 메시지 발행의 실패로 끝
정리 #
중앙 집중 DB의 장애, 전체 시스템의 전파 -> MQ를 이용한 이벤트 기반 통신으로 시스템간 영향도를 분리
대용량 데이터 #
-
주문 아키텍처
-
정규화된 주문 DB에서 저장 + 조회가 함께 발생
-
주문 내역 정보에는 많은 정보가 포함되어있음
해결 #
-
정규화된 주문 애그리거트는 수많은 조인이 발생 -> 조회 성능을 높이기위해 단일 도큐먼트로 역정규화
-
단순 단일 도큐먼트 조회만으로 주문 정보를 가져올 수 있음 (with MongoDB)
-
주문 도메인 생명주기 : 주문 도메인은 생명주기에서만 도메인 변경이 발생
-
주문 도메인 생명주기에 발생되는 도메인 이벤트를 통해 데이터 동기화 수행
-
CQRS 적용 아키텍처 : 저장과 조회를 분리한 아키텍처
정리 #
대용량 데이터 RDB 조회 성능 저하 -> 커맨드 모델과 조회 모델을 분리, 조회 모델 역정규화를 통해 조회 성능 개
대규모 트랜잭션 #
-
주문 DB의 분당 쓰기 처리량 한계치 도달
-
쓰기 요청의 증가 : 스펙업으로 대응 (최고사양의 스펙으로도 처리량을 감당 불가능)
해결 #
-
샤딩
-
애플리케이션 샤딩 구현
- 고민 1) 샤드 클러스터 내 어느 샤드에 접근할지 결정하는 샤딩 전략
- 고민 2) 여러 샤드에 있는 데이터를 애그리게이트 하는 방법에 대한 고민
-
샤딩 전략
-
- Key Based Sharding : Shard Key를 이용하여 데이터 소스를 결정하는 방식 (Hash Based Sharding)
-
- Range Based Sharding : 값의 범위(Range) 기반으로 데이터를 분산시키는 방식
-
- Directory Based Sharding : 샤드가 어떤 데이터를 가질지 look up table을 유지하는 방식
-
1. Key Based Sharding #
- 장점 : 구현 간단, 데이터를 샤드에 골고루 분배 가능
- 단점 : 장비를 동적으로 추가, 제거할때 데이터 재배치 필요
2. Range Based Sharding #
- 장점 : 특정 값의 범위 기반으로 샤드를 결정하면 되기 때문에 구현이 간단
- 단점 : 데이터가 균등하게 배분되지 않아 특정 샤드에 데이터가 몰리면 Hotspot이 되어 성능 저하 발생
3. Directory Based Sharding #
- 장점 : 샤드 결정 로직이 Look Up Table로 분리되어있어 동적으로 샤드 추가하는데 유리
- 단점 : 단일 장애 포인트
주문 시스템의 특징 주문이 정상 동작하지 않으면, 서비스 전체의 좋지않은 경험으로 이어지고, 동적 주문 데이터는 최대 30일만 저장한다. -> 단일 장애 포인트를 피하고, 샤드 추가 이후 30일이 지나면 데이터는 다시 균등하게 분배된다.
샤드키 주문번호를 통해 주문 순번을 알 수 있다. ->
B1MU00584X
: 주문순번 % 샤드 수 = 샤드번호
정리 #
주문번호 샤드키를 이용한 해싱은 주문 순번 순으로 샤드에 고르게 분배된다.
-
다건 조회는 대용량 처리르 위해 몽고DB를 활용했고, 저장&조회 로직을 분리해둔 덕분에 애플리케이션 샤딩 적용시 큰 도움이 되었다.
- N개의 샤드에 분산 저장된 데이터를 조합하여 내려주는것을 해결할 수 있었음
-
쓰기 요청 증가 스케일 아웃 대응 샤딩으로 인해 증가하는 트랜잭션을 스케일 아웃으로 대응 가능
-
샤딩이 적용된 아키텍처 모습
복잡한 이벤트 아키텍처 #
-
규칙성 없는 무분별한 이벤트 발행
-
주요 도메인 로직과 서비스 로직을 이벤트 기반으로 관심사를 분리
-
주문 시스템의 이벤트 아키텍처
-
문제점1. 스프링 애플리케이션 이벤트는 로직을 수행하는 주체를 파악하기 어려움
-
문제점2. 이벤트 유실이 발생할 경우 재처리가 어려움
해결 #
-
내부 / 외부 이벤트 정리
-
ZERO Payload 이벤트 처리기가 모든 서비스 로직을 처리 필요한 데이터는 주문저장소(MongoDB) 조회
-
이벤트 처리 주체의 단일화 네트워크 비용보다 이벤트 처리 주체의 단일화에 이점이 있다.
또다른 문제 #
-
이벤트 발행 실패 유형
-
트랜잭션 내부 외부에서 발행 실패 유무에 따라 처리가 달라진다.
해결 #
-
트랜잭션 아웃박스 패턴
- 이벤트 발행 실패와 서비스 실패를 격리하여 재발행 수단을 보장한다.
-
이벤트 발행 실패시, OUTBOX 엔티티에 저장된 페이로드를 재발행한다.
- 유실된 데이터를 배치로 재발행
정리 #
규칙성 없는 무분별한 이벤트 발행 -> 이벤트 로직을 단일 애플리케이션에 위임하여 관리 포인트를 집중