개발/도서 스터디
[대규모 시스템 설계 기초2] 7장 호텔 예약 시스템
방푸린
2025. 1. 27. 15:52
반응형
포인트
- 동시성은 높으나 초당 예약 건수는 높지 않음
- 약간의 지연시간 가능
데이터베이스로 RDB 선택
- 인덱스 등을 사용하여 읽기가 압도적인 흐름을 잘 지원(no sql은 쓰기에 빠름)
- ACID 보장(이중 청구, 이중 예약, 잔액 마이너스 등 방지)
- 데이터 모델링(호텔, 객실 등) 가능
- 7,300만 개 정도의 데이터는 하나의 데이터베이스로 저장하기에 충분하지만 SPOF가능성이 있어 replica를 두는 게 좋다.
- 데이터가 많아진다면 현재 및 향후 데이터만 저장하고 나머지는 cold storage에 옮기거나
- 데이터 베이스를 호텔 키를 기반으로 샤딩한다.
동시성; 이중 예약 문제
- 멱등성 api; 주문 키를 디비 pk로 사용하여 두 번 저장되지 않게
- 서로 다른 사용자의 동시 디비 접근을 막기 위해 디비 락
- 비관락 select for update 충돌이 있을 것이라 가정하고 미리 락; 모든 연산을 직렬화; 데이터에 대한 경합이 심할 때; 교착 상태 빠질 수, 성능 낮아짐
- 낙관락: 테이블에 버저닝, 락을 걸지 않아 비관락보다 빠름 하지만 동시성 수준이 높으면 성능이 급격히 나빠짐
- constraint(디비 제약조건); 낙관락과 유사, 제약 조건 맞으면 롤백; 디비별로 지원하지 않을 수도
규모 확장
- 호텔 아이디를 기반으로 한 데이터베이스 샤딩
- 예약 서비스는 잔여 객실 질의는 캐시에다 하고 갱신은 디비에다 한다. 디비에 갱신이 일어나면 비동기로 캐시 데이터를 갱신한다.
- 캐시: 낡은 데이터 소멸되도록 TTL 설정; 레디스를 두고 잔여 객실 질의할 때 캐시를 쓸 수 있게
- 키: hotelId_roomtypeId_yyyymmdd
- 값: 잔여 객실 수
- 캐시 갱신: 비동기로
- 갱신은 어플리케이션 단에서 할 수도 있고 카프카 소스 커넥터 + 디비지움(CDC)를 사용하여 디비 변경 사항을 감지하여 캐시에 반영하게 한다.
MSA 일관성
여러 개의 단일 트랜젝션을 어떻게 일치시킬까
2PC: 여러 노드에 걸친 하나의 트랜젝션
한 노드에 장애 나면 중단; 트랜젝션 참여 노드가 많아질수록 통신 오버헤드와 응답 지연 증가
1단계: 준비 단계 (Prepare Phase)
- 코디네이터(또는 트랜잭션 관리자)가 트랜잭션에 참여하는 모든 노드에 Prepare 명령
- 각 노드는 트랜잭션을 수행할 준비가 되었는지 확인하고, 로컬에서 트랜잭션의 상태를 저장(로그 기록)한 뒤, 코디네이터에게 승인(YES) 또는 거부(NO)를 응답
- 응답이 YES이면 해당 작업을 커밋할 준비가 되었다는 의미.
- 응답이 NO이면 트랜잭션을 중단해야 한다는 의미.
2단계: 커밋 또는 롤백 단계 (Commit or Rollback Phase)
- 모든 노드가 YES를 응답하면 코디네이터는 트랜잭션을 커밋(Commit)
- 한 노드라도 NO를 응답하면 코디네이터는 트랜잭션을 롤백(Rollback)
- 각 노드는 코디네이터의 명령에 따라 커밋 또는 롤백을 수행한 뒤 결과를 다시 코디네이터에게 알림
사가: SAGA 트랜잭션은 분산 시스템에서 장기 실행 트랜잭션을 관리하기 위한 설계 패턴으로, 분산 트랜잭션의 일관성을 보장하면서도 2PC의 성능 및 확장성 문제를 해결하기 위해 고안
- 데이터의 최종적 일관성(Eventual Consistency)을 보장.
- 보상 작업(Compensating Transaction)을 통해 롤백 대신 이전 상태로 복구.
- 분산 락(Distributed Lock)을 사용하지 않아 확장성과 성능이 뛰어남.
- 네트워크 및 시스템 장애에 대한 복원력을 높임.
- Choreography (코레오그래피)
- 각 서비스가 다른 서비스로 직접 이벤트를 발행하고 구독.
- 중앙 제어 지점이 없음.
- 유연성이 높지만, 서비스 간 결합도가 증가할 수 있음.
- 예시:
- A 서비스가 작업 완료 후 이벤트를 발행 → B 서비스가 이벤트를 받아 다음 작업 수행 → C 서비스도 같은 방식으로 진행.
- Orchestration (오케스트레이션)
- 중앙 컨트롤러(오케스트레이터)가 각 서비스를 호출하고 트랜잭션을 제어.
- 서비스 간 결합도는 낮지만, 중앙 집중식 제어가 필요.
- 예시:
- 중앙 오케스트레이터가 A, B, C 서비스를 순차적으로 호출하고 결과에 따라 보상 작업 수행.
SAGA 트랜잭션의 기본 흐름
- 각 단계(Step)는 독립적인 로컬 트랜잭션으로 실행되고 커밋.
- Step 중 하나가 실패하면 이전 단계에서 실행된 트랜잭션을 보상 작업으로 되돌림.
- 전체 작업이 성공하거나 보상 작업이 완료될 때까지 진행.
2024.02.29 - [architecture/micro service] - [arch] EDA, event sourcing, saga, 2pc
728x90
반응형