읽은 책/[책] 가상 면접 사례로 배우는 대규모 시스템 설계 기초 2권

7장. 호텔 예약 시스템

코드몬스터 2024. 8. 18. 08:43
728x90

1단계: 설계 범위

1. 기능 요구사항

  • 호텔 정보 페이지 표시
  • 객실 정보 페이지 표시
  • 객실 예약 지원
  • 호텔이나 객실 정보를 추가/삭제/갱신하는 관리자 페이지 지원
  • 초과 예약 지원

2. 비기능 요구 사항

  • 높은 수준의 동시성
  • 적절한 지연 시간

3. 개략적 규모 추정

  • 총 5,000개 호텔, 100만개의 객실
  • 평균 객실의 70%가 사용 중이고, 평균 투숙 기간은 3일이라고 가정
  • 일일 예상 예약 건수: 233,333
  • 초당 예약 건수  ~3., 그다지 높지 않다.

2단계: 개략적 설계안

1. API 설계

  • reservationID는 이중 예약을 방지하고자 동일한 예약은 단 한 번만 이루어지도록 보증하는 멱등 키(idempotent key)다.
  • 이중 예약은 같은 날 같은 객실에 예약이 중복으로 이루어지는 것을 말한다.(동시성 문제)

호텔 관련 API

API 설명
GET /v1/hotels/id 호텔의 상세 정보 반환
POST /v1/hotels 신규 호텔 추가. 호텔 직원만 가능
PUT /v1/hotels/id 호텔 정보 갱신. 호텔 직원만 가능
DELETE /v1/hotels/id 호텔 정보 삭제. 호텔 직원만 가능

 

객실 관련 API

예약 관련 API

 

 

2. 데이터 모델

호텔 예약 시스템은 아래 질의를 지원해야 한다.

  1. 호텔 상세 정보 확인
  2. 지정된 날짜 범위 사용 가능한 객실 유형 확인
  3. 예약 정보 기록
  4. 예약 내역 또는 과거 예약 이력 정보 조회

이러한 기능을 지원하기 위해서 관계형 데이터베이스를 선택하고 이유는 아래와 같다.

  • 읽기 빈도가 쓰기 연산에 비해 높은 작업 흐름을 지원한다.
    • NoSQL은 대체로 쓰기 연산에 최적화 되어있다.
  • ACID(원자성, 일관성, 격리성, 영속성을) 보장하는데 예약 시스템을 만드는 경우 해당 속성이 중요하다.
  • 데이터를 쉽게 모델링할 수 있다.

 

예약 상태

  • 결제 대기, 결제 완료, 환불 완료, 취소, 승인 실패의 다섯 상태가 있다.

3. 개략적 설계안

  • 호텔 예약 시스템은 마이크로서비스 아키텍처를 사용한다.
  • 사용자: 휴대폰이나 컴퓨터로 객실 예약 당사자
  • 관리자: 호텔 직원
  • CDN: 정적 콘텐츠를 캐시하여 웹사이트 로드 성능을 개선
  • 공개 API 게이트웨이: 체리율 제한, 인증 등의 기능을 지원하는 완전 관리형 서비스
  • 내부 API: 호텔 직원만 사용가능한 API
  • 호텔 서비스: 호텔과 객실에 대한 상세 정보를 제공
  • 요금 서비스: 미래의 어떤 날에 어떤 요금을 받아야 하는지 데이터를 제공
  • 예약 서비스: 예약 요청을 받고 객실을 예약하는 과정을 처리
  • 결제 서비스: 고객의 결제를 맡아 처리
  • 호텔 관리 서비스: 승인된 호텔직원만 사용 가능한 서비스

3단계: 상세 설계

1. 개선된 데이터 모델

  • room: 객실에 관계된 정보
  • room_type_rate: 특정 객실 유형의 특정 일자 요금 정보
  • reservation: 투숙객 예약 정보
  • room_type_inventory: 호텔의 모든 객실 유형 테이블
    • hotel_id: 호텔 식별자
    • room_type_id: 객실 유형 식별자
    • date: 일자
    • total_inventory: 총 객실의 수에서 일시적으로 제외한 객실 수를 뺀 값
    • total_reserved: hotel_id, room_type_id, date에 예약된 모든 객실의 수

 

  • room_type_inventory 테이블은 고객이 특정 유형의 객실을 예약할 수 있는지 여부를 확인할 때 사용
    • 입력: startDate, endDate, roomTypeId, hotelId, numberOfRoomsToReserve
    • 출력: 사용자가 예약 가능한 상태이면 True를 반환, 아니면 False를 반환
    • if (total_reserved + ${ numberOfRoomsToReserve}) <= total_inventory)

2. 동시성 모델

이중 예약을 어떻게 방시할 것인가

  1. 같은 사용자가 예약 버튼을 여러번 누를 수 있다.
  2. 여러 사용자가 같은 객실을 동시에 예약하려할 수 있다.

 

첫 번째 시나리오

  • 클라이언트 측 구현: 클라이언트가 요청을 전송하고 난 다음에 '예약' 버튼을 회색으로 표시하거나, 숨기거나, 비활성화하는 것이다. 가령 사용자가 자바스크립트를 비활성화하면 클라이언트 측 확인 절차는 우회할 수 있다.
  • 멱등 API: 예약 API 요청에 멱등 키를 추가하는 방안이다.
    • 몇 번을 호출해도 같은 결과를 내는 API를 멱등 API라고 부른다.

 

두 번재 시나리오

 

3. 시스템의 규모 확장