SiliconValley_survivor

SiliconValley_survivor

Design Airbnb & Hotel Reservation - 호텔 예약을 CRUD로 설계한 사람이 면접에서 막히는 이유

많은 사람이 예약 시스템을 reservation CRUD로 시작하지만, 실제 호텔 도메인에서는 room_type_inventory, 날짜별 재고 차감, overbooking, idempotency, race condition이 더 중요하다. 이번 글에서는 호텔 예약 시스템을 데이터베이스와 동시성 관점에서 풀어봅니다.

SiliconValley_survivor's avatar
SiliconValley_survivor
Apr 02, 2026
∙ Paid

호텔 예약 시스템

이번 글에서는 Airbnb & Marriott International 같은 호텔 체인을 위한 호텔 예약 시스템을 설계한다. 이 장에서 사용한 설계와 기법은 다른 인기 있는 예약 관련 인터뷰 주제에도 적용할 수 있다.

  • Airbnb 설계

  • 경량 예약 시스템 설계

  • 영화 티켓 예약 시스템 설계


1. 문제를 이해하고 설계 범위를 정하기

호텔 예약 시스템은 복잡하고, 그 구성 요소는 비즈니스 사용 사례에 따라 달라진다. 설계에 들어가기 전에, 범위를 좁히기 위해 면접관에게 Clarifying Questions 단게를 거쳐야 합니다.

지원자

시스템의 규모는 어느 정도인가요?

면접관

총 5,000개의 호텔과 100만 개의 객실을 가진 호텔 체인을 위한 웹사이트를 만든다고 가정합시다.

지원자

고객은 예약할 때 결제하나요, 아니면 호텔에 도착했을 때 결제하나요?

면접관

단순화를 위해, 예약할 때 전액 결제한다고 합시다.

지원자

고객은 호텔 웹사이트를 통해서만 객실을 예약하나요? 전화 통화 같은 다른 예약 옵션도 지원해야 하나요?

면접관

사람들이 호텔 웹사이트나 앱을 통해 호텔 객실을 예약할 수 있다고 가정합시다.

지원자

고객이 예약을 취소할 수 있나요?

면접관

네.

지원자

우리가 고려해야 할 다른 사항이 있나요?

면접관

네, 우리는 10% 초과예약(overbooking)을 허용합니다.

혹시 모르신다면, 초과예약은 호텔이 실제 보유 객실 수보다 더 많은 객실을 판매하는 것을 의미합니다. 호텔은 일부 고객이 예약을 취소할 것이라는 예상 하에 이렇게 합니다.

지원자

시간이 제한되어 있으므로, 호텔 객실 검색은 범위에 포함되지 않는다고 가정하겠습니다. 우리는 다음 기능들에 집중하겠습니다.

  • 호텔 관련 페이지 보여주기

  • 호텔 객실 관련 상세 페이지 보여주기

  • 객실 예약하기

  • 호텔 또는 객실 정보를 추가/삭제/수정하는 관리자 패널

  • 초과예약 기능 지원하기

면접관

좋습니다.

한 가지 더 있습니다. 호텔 가격은 동적으로 변합니다. 호텔 객실 가격은 특정 날짜에 호텔이 얼마나 찰 것으로 예상되는지에 따라 달라집니다. 이 면접에서는 가격이 매일 달라질 수 있다고 가정할 수 있습니다.

지원자

그 점을 염두에 두겠습니다.

다음으로, 가장 중요한 비기능 요구사항에 대해 이야기할 수 있다.


Non-Functional Requirements - 비기능 요구사항

  • 높은 동시성을 지원해야 한다. 성수기나 큰 이벤트 기간에는 일부 인기 호텔에 대해 많은 고객이 같은 객실을 예약하려고 시도할 수 있다.

  • 중간 정도의 지연 시간. 사용자가 예약을 할 때 빠른 응답 시간이 이상적이지만, 시스템이 예약 요청을 처리하는 데 몇 초가 걸리는 것은 허용 가능하다.


Estimated Scale

  • 5,000개 호텔, 총 100만 개 객실

  • 객실의 70%가 점유 중이고 평균 숙박 기간이 3일이라고 가정

일일 예약 수 추정

1 million × 0.7 / 3 = 233,333
(반올림하여 약 240,000)

초당 예약 수

240,000 / 10^5 seconds in a day ~= 3

보는 바와 같이 평균 예약 TPS(transaction per second)는 높지 않다.

다음으로 시스템 내 모든 페이지의 QPS를 대략 계산해 보자. 일반적인 고객 흐름에는 세 단계가 있다.

  1. 호텔/객실 상세 페이지 보기. 사용자는 이 페이지를 둘러본다 - Query

  2. 예약 페이지 보기. 사용자는 날짜, 투숙객 수, 결제 정보 등 예약 세부사항을 확인한 뒤 예약할 수 있다 - Query

  3. 객실 예약하기. 사용자는 “book” 버튼을 클릭해 객실을 예약하고 객실은 예약 처리된다 - Transaction

사용자의 약 10%가 다음 단계로 넘어가고, 최종 단계에 도달하기 전에 90%의 사용자가 이탈한다고 가정하자. 또한 prefetching 기능이 구현되어 있어 사용자가 다음 단계에 도달하기 전에 일부 콘텐츠를 미리 가져온다고 가정할 수 있다.

서로 다른 단계에서 QPS가 대략 어떤 모습일지 보여준다. 최종 예약 TPS가 3이므로 퍼널을 따라 거꾸로 계산할 수 있다. 주문 확인 페이지의 QPS는 30이고 상세 페이지의 QPS는 300이다.


QPS 분포

           [호텔/객실 상세 보기]
              (QPS = 300)
                   /\
                  /  \
                 /    \
                /      \
               /        \
           [예약 주문 페이지 보기]
               (QPS = 30)
                   /\
                  /  \
                 /    \
                /      \
              [객실 예약하기]
               (QPS = 3)

High-Level Design

이 섹션에서는 다음을 논의한다

  • API 설계

  • 데이터 모델

  • 상위 수준 설계


API 설계

호텔 예약 시스템의 API 설계를 살펴본다. 가장 중요한 API들은 아래에 RESTful 규칙을 사용해 나열되어 있다.

완전한 호텔 웹사이트를 위해서는, 고객이 다양한 기준에 따라 객실을 검색할 수 있도록 직관적인 기능을 제공해야 한다. 이러한 검색 기능용 API는 중요하지만 기술적으로 도전적인 부분은 아니다. 따라서 Out of Scope 에 해당된다.


API Signatures

호텔 API

GET /v1/hotels/ID
-> 호텔에 대한 상세 정보를 가져온다.

POST /v1/hotels
-> 새 호텔을 추가한다. 이 API는 호텔 직원만 사용할 수 있다.

PUT /v1/hotels/ID
-> 호텔 정보를 수정한다. 이 API는 호텔 직원만 사용할 수 있다.

DELETE /v1/hotels/ID
-> 호텔을 삭제한다. 이 API는 호텔 직원만 사용할 수 있다.

객실 관련 API

GET /v1/hotels/ID/rooms/ID
-> 객실에 대한 상세 정보를 가져온다.

POST /v1/hotels/ID/rooms
-> 객실을 추가한다. 이 API는 호텔 직원만 사용할 수 있다.

PUT /v1/hotels/ID/rooms/ID
-> 객실 정보를 수정한다. 이 API는 호텔 직원만 사용할 수 있다.

DELETE /v1/hotels/ID/rooms/ID
-> 객실을 삭제한다. 이 API는 호텔 직원만 사용할 수 있다.

예약 관련 API

GET /v1/reservations
-> 로그인한 사용자의 예약 이력을 가져온다.

GET /v1/reservations/ID
-> 예약에 대한 상세 정보를 가져온다.

POST /v1/reservations
-> 새 예약을 만든다.

DELETE /v1/reservations/ID
-> 예약을 취소한다.

새 예약을 만드는 것은 매우 중요한 기능이다. 새 예약을 만드는 요청 파라미터(POST /v1/reservations)는 다음과 같을 수 있다.

{
  "startDate": "2021-04-28",
  "endDate": "2021-04-30",
  "hotelID": "245",
  "roomID": "U12354673389",
  "reservationID": "13422445"
}

reservationID는 이중 예약(double booking)을 방지하기 위한 멱등성 키(idempotency key)로 사용된다는 점에 유의해야 합니다.

이중 예약이란 같은 날 같은 객실에 대해 여러 예약이 만들어지는 것을 의미합니다.


데이터 모델

어떤 데이터베이스를 사용할지 결정하기 전에, 데이터 접근 패턴을 자세히 살펴보자.

호텔 예약 시스템에서는 다음 질의를 해야 합니다.

Query 1

호텔의 상세 정보를 조회한다.

Query 2

날짜 범위가 주어졌을 때 이용 가능한 객실 유형을 찾는다.

Query 3

예약을 기록한다.

Query 4

예약 또는 예약 이력을 조회한다.

대략적인 규모 추정으로부터, 이 시스템의 규모는 크지 않지만 큰 이벤트 동안의 트래픽 급증에는 대비해야 한다는 것을 알 수 있다.

이러한 요구사항을 염두에 두고, 우리는 관계형 데이터베이스를 선택한다. 이유는 다음과 같다.

  • 관계형 데이터베이스는 읽기 비중이 높고 쓰기 빈도는 상대적으로 낮은 워크플로우에 잘 맞는다. 이는 호텔 웹사이트/앱을 방문하는 사용자 수가 실제로 예약을 하는 사용자 수보다 몇 자릿수나 더 많기 때문이다. NoSQL 데이터베이스는 일반적으로 쓰기에 최적화되어 있으며, 관계형 데이터베이스는 읽기 중심 워크플로우에 충분히 잘 작동한다.

  • 관계형 데이터베이스는 ACID(원자성, 일관성, 고립성, 지속성) 보장을 제공한다.
    ACID 속성은 예약 시스템에서 중요하다. 이런 속성이 없으면 잔액 마이너스, 이중 청구, 이중 예약 같은 문제를 방지하기가 쉽지 않다. ACID 속성은 애플리케이션 코드를 훨씬 단순하게 만들고 시스템 전체를 더 쉽게 추론할 수 있게 해 준다. 관계형 데이터베이스는 보통 이러한 보장을 제공한다.

  • 관계형 데이터베이스는 데이터를 쉽게 모델링할 수 있다.
    비즈니스 데이터의 구조와 서로 다른 엔터티(호텔, 객실, 객실 유형 등) 간의 관계가 매우 명확하고 안정적이다. 이런 종류의 데이터 모델은 관계형 데이터베이스로 쉽게 모델링된다.

이제 관계형 데이터베이스를 데이터 저장소로 선택했으니, 스키마 설계를 살펴보자. 아래 스키마는 단순한 스키마 설계를 보여주며, 많은 후보자들이 호텔 예약 시스템을 모델링할 때 가장 자연스럽게 떠올리는 방식입니다.


Core Entities

+---------------------------+
| Hotel Service             |
|---------------------------|
| hotel                     |
| hotel_id      PK          |
| name                      |
| address                   |
| location                  |
+---------------------------+

+---------------------------+
| Rate Service              |
|---------------------------|
| room_type_rate            |
| hotel_id      PK          |
| date          PK          |
| rate                      |
+---------------------------+

+---------------------------+
| Guest Service             |
|---------------------------|
| guest                     |
| guest_id      PK          |
| first_name                |
| last_name                 |
| email                     |
+---------------------------+

+---------------------------+
| Hotel Service             |
|---------------------------|
| room                      |
| room_id       PK          |
| room_type_id              |
| floor                     |
| number                    |
| hotel_id                  |
| name                      |
| is_available              |
+---------------------------+

+---------------------------+
| Reservation Service       |
|---------------------------|
| reservation               |
| reservation_id PK         |
| hotel_id                  |
| room_id                   |
| start_date                |
| end_date                  |
| status                    |
| guest_id                  |
+---------------------------+

대부분의 속성은 이름만 봐도 알 수 있으므로, 예약 테이블의 status 필드만 설명하겠다. status 필드는 다음 상태 중 하나일 수 있다

pending, paid, refunded, canceled, rejected.

상태 머신은 아래 다이어그램에 나와 있다.


예약 상태

                 [Pending]
                /    |    \
               /     |     \
              v      v      v
       [Canceled]  [Paid] [Rejected]
                     |
                     v
                 [Refunded]

이 스키마 설계에는 큰 문제가 있다. 이 데이터 모델은 사용자가 예약할 때 room_id(listing_id라고 불릴 수도 있다)가 주어지는 Airbnb 같은 회사에는 잘 맞는다. 하지만 호텔은 그렇지 않다.

사용자는 실제로 특정 객실이 아니라, 특정 호텔에서 객실 유형(a type of room) 을 예약한다. 예를 들어, 객실 유형은 스탠다드룸, 킹사이즈 침대가 있는 객실, 퀸사이즈 침대 두 개가 있는 객실 등이 될 수 있다. 객실 번호는 예약 시점이 아니라 고객이 체크인할 때 주어진다.

이 새로운 요구사항을 반영하기 위해 데이터 모델을 개선해야 한다.


이 호텔 예약 시스템에는 마이크로서비스 아키텍처를 사용한다. 지난 몇 년 동안 마이크로서비스 아키텍처는 큰 인기를 얻었다. 마이크로서비스 아키텍처를 사용하는 회사에는 Amazon, Netflix, Uber, Airbnb, Twitter 등이 있다. 마이크로서비스 아키텍처의 장점에 대해 더 알고 싶다면, 아래 글에서 자세히 알아보실 수 있습니다.

마이크로서비스 아키텍처를 바탕으로 모델링되었고, High-Level Design 다이어그램은 아래와 같습니다.


High Level Design

External
  |
  +--> CDN <--> User
                  |
------------------ Public / Private boundary ------------------
                  |
            Public API Gateway
             /      |       |       \
            /       |       |        \
           v        v       v         v
   Hotel Service  Rate   Reservation  Payment
                  Service   Service    Service
       |            |          |          |
       v            v          v          v
  Hotel Cache    Rate DB   Reservation DB Payment DB
       |
       v
    Hotel DB

Private side
Admin
  |
  v
Internal API
  |
  v
Hotel Management Service

이제 각 구성 컴포넌트를 살펴보도록 합니다.

  • User - 사용자는 모바일 폰이나 컴퓨터에서 호텔 객실을 예약한다.

  • Admin (hotel staff) - 권한 있는 호텔 직원은 고객 환불, 예약 취소, 객실 정보 수정 등의 관리 작업을 수행한다.

  • CDN (content delivery network) - 더 나은 로드 시간을 위해 CDN은 자바스크립트 번들, 이미지, 비디오, HTML 등 모든 정적 자산을 캐시하는 데 사용된다.

  • Public API Gateway - 이 서비스는 rate limiting, 인증 등을 지원하는 완전 관리형 서비스이다. API 게이트웨이는 엔드포인트에 따라 요청을 특정 서비스로 전달하도록 구성된다. 예를 들어, 호텔 홈페이지를 로드하는 요청은 hotel service로 전달되고, 호텔 객실을 예약하는 요청은 reservation service로 라우팅된다.

  • Internal APIs - 이러한 API는 권한 있는 호텔 직원만 사용할 수 있다. 일반적으로 내부 소프트웨어나 웹사이트를 통해 접근 가능하다. 보통 VPN(virtual private network)으로 한 번 더 보호된다.

  • Hotel Service - 호텔과 객실에 대한 상세 정보를 제공한다. 호텔 데이터와 객실 데이터는 일반적으로 정적이므로 쉽게 캐시할 수 있다.

  • Rate Service - 미래 날짜에 대한 객실 요금을 제공한다. 호텔 산업에서 흥미로운 사실 하나는 객실 가격이 특정 날짜에 호텔이 얼마나 찰 것으로 예상되는지에 따라 달라진다는 점이다.

  • Reservation Service - 예약 요청을 받고 호텔 객실을 예약한다. 이 서비스는 또한 객실이 예약되거나 예약이 취소될 때 객실 재고를 추적한다.

  • Payment Service - 고객으로부터 결제를 실행하고, 결제 트랜잭션이 성공하면 예약 상태를 paid로 갱신하고, 실패하면 rejected로 갱신한다.

  • Hotel Management Service - 권한 있는 호텔 직원만 사용할 수 있다. 호텔 직원은 이 서비스를 통해 다음 기능을 사용할 수 있다. 예정된 예약 기록 보기, 고객을 대신해 객실 예약하기, 예약 취소하기 등.

명확히 하자면, 마이크로서비스 간 상호작용 화살표를 많이 생략했다. 예를 들어, 아래 다이어그램을 보시듯이 Reservation service와 Rate service 사이에는 화살표가 있어야 합니다.

Reservation service는 객실 요금을 얻기 위해 Rate service를 조회한다. 이는 예약의 총 객실 요금을 계산하는 데 사용된다. 또 다른 예로, Hotel Management Service는 대부분의 다른 서비스들과 연결되는 여러 화살표가 있어야 한다.

관리자가 Hotel Management Service를 통해 변경을 수행하면, 변경 처리를 위해 요청은 실제로 데이터를 소유한 해당 서비스로 전달된다.


서비스 간 연결

예시 1
[Reservation Service]
          |
          v
    [Rate Service]

예시 2
              [Hotel Management Service]
                 /      |        |       \
                v       v        v        v
      [Hotel Service] [Rate] [Reservation] [......]
                         Service   Service

프로덕션 시스템에서는 서비스 간 통신에 gRPC 같은 현대적이고 고성능의 원격 프로시저 호출(RPC) 프레임워크를 자주 사용한다. 이러한 프레임워크를 사용하면 많은 장점이 있다.


Deep Dive

이제 High-Level Design 에 대해 이야기했으니, 다음 항목을 더 깊게 살펴보자.

  • 개선된 데이터 모델

  • 동시성 이슈

  • 시스템 확장

  • 마이크로서비스 아키텍처에서의 데이터 불일치 해결


개선된 Core Entities

고수준 설계에서 언급했듯, 호텔 객실을 예약할 때 실제로는 특정 객실이 아니라 객실 유형(type of room) 을 예약한다. 이를 수용하려면 API와 스키마에 무엇을 바꿔야 할까?

예약 API의 경우, 요청 파라미터에서 roomID는 roomTypeID로 대체된다. 새 예약을 만드는 API는 다음과 같다.

POST /v1/reservations

요청 파라미터

{
  "startDate": "2021-04-28",
  "endDate": "2021-04-30",
  "hotelID": "245",
  "roomTypeID": "12354673389",
  "reservationID": "13422445"
}

개선된 스키마는 아래와 같습니다.


Core Entities V2

+---------------------------+
| Hotel Service             |
|---------------------------|
| hotel                     |
| hotel_id      PK          |
| name                      |
| address                   |
| location                  |
+---------------------------+

+---------------------------+
| Rate Service              |
|---------------------------|
| room_type_rate            |
| hotel_id      PK          |
| date          PK          |
| rate                      |
+---------------------------+

+---------------------------+
| Guest Service             |
|---------------------------|
| guest                     |
| guest_id      PK          |
| first_name                |
| last_name                 |
| email                     |
+---------------------------+

+---------------------------+
| Hotel Service             |
|---------------------------|
| room                      |
| room_id       PK          |
| room_type_id              |
| floor                     |
| number                    |
| hotel_id                  |
| name                      |
| is_available              |
+---------------------------+

+-------------------------------+
| Reservation Service           |
|-------------------------------|
| room_type_inventory           |
| hotel_id                      |
| room_type_id                  |
| date                          |
| total_inventory               |
| total_reserved                |
+-------------------------------+

+-------------------------------+
| Reservation Service           |
|-------------------------------|
| reservation                   |
| reservation_id   PK           |
| hotel_id                      |
| room_type_id                  |
| start_date                    |
| end_date                      |
| status                        |
| guest_id                      |
+-------------------------------+

가장 중요한 테이블 몇 개를 간단히 살펴보겠다.

  • room - 객실에 관한 정보를 담고 있다.

  • room_type_rate - 미래 날짜에 대한 특정 객실 유형의 가격 데이터를 저장한다.

  • reservation - 고객 예약 데이터를 기록한다.

  • room_type_inventory - 호텔 객실에 대한 재고 데이터를 저장한다. 이 테이블은 예약 시스템에서 매우 중요하므로, 각 컬럼을 자세히 살펴보자.

    • hotel_id: 호텔의 ID.

    • room_type_id: 객실 유형의 ID.

    • date: 하루 단위의 날짜.

    • total_inventory: 전체 객실 수에서 일시적으로 재고에서 제외된 객실을 뺀 수. 일부 객실은 유지보수를 위해 시장에서 제외될 수 있다.

    • total_reserved: 지정된 hotel_id, room_type_id, date에 대해 예약된 전체 객실 수.

room_type_inventory 테이블을 설계하는 다른 방법들도 있지만, 날짜별로 한 행을 두는 방식은 날짜 범위 내 예약 관리와 질의를 쉽게 만들어 준다.

(hotel_id, room_type_id, date) 는 복합 기본 키(composite primary key)이다. 이 테이블의 행들은 향후 2년 동안의 모든 미래 날짜에 대한 재고 데이터를 조회하여 미리 채워 넣는다. 우리는 날짜가 더 멀어질 때 재고 데이터를 미리 채워 넣는 스케줄된 일일 작업을 가지고 있다.

이제 스키마 설계를 마무리했으니, 저장 용량에 대해 추정해 보자. 대략적인 규모 추정에서 언급했듯이, 호텔은 5,000개다. 각 호텔에 20개의 객실 유형이 있다고 가정하자. 그러면 (5,000 hotels × 20 types of rooms × 2 years × 365 days) = 73 million rows 가 된다. 7,300만 행은 많은 데이터가 아니며 단일 데이터베이스만으로도 데이터를 저장하기에 충분하다.

그러나 단일 서버는 단일 장애 지점(single point of failure)을 의미한다. 고가용성을 달성하기 위해 여러 리전 또는 가용 영역에 걸쳐 데이터베이스 복제를 설정할 수 있다.

아래는 room_type_inventory 테이블의 샘플 데이터를 보여줍니다.


room_type_inventory 테이블의 샘플 데이터

hotel_id | room_type_id |    date    | total_inventory | total_reserved
---------|--------------|------------|-----------------|---------------
211      | 1001         | 2021-06-01 | 100             | 80
211      | 1001         | 2021-06-02 | 100             | 82
211      | 1001         | 2021-06-03 | 100             | 86
211      | 1001         |    ...     | ...             | ...
211      | 1002         | 2023-05-31 | 100             | 0
2210     | 101          | 2021-06-01 | 200             | 164
2210     | 101          | 2021-06-01 | 30              | 23
2210     | 101          | 2021-06-02 | 30              | 25

room_type_inventory 테이블은 고객이 특정 객실 유형을 예약할 수 있는지 여부를 확인하는 데 사용된다. 예약에 대한 입력과 출력은 다음과 같을 수 있다.

  • Input

    • startDate (2021-07-01), endDate (2021-07-03), roomTypeId, hotelId, numberOfRoomsToReserve

  • Output

    • 지정된 객실 유형에 재고가 있어 사용자가 예약할 수 있으면 True. 그렇지 않으면 False를 반환한다.

SQL 관점에서 보면, 이는 다음 두 단계로 이루어진다.

1. 날짜 범위 내 행 선택

SELECT date, total_inventory, total_reserved
FROM room_type_inventory
WHERE room_type_id = ${roomTypeId} AND hotel_id = ${hotelId}
AND date between ${startDate} and ${endDate}

이 질의는 다음과 같은 데이터를 반환한다.


호텔 재고

date       | total_inventory | total_reserved
-----------|-----------------|---------------
2021-07-01 | 100             | 97
2021-07-02 | 100             | 96
2021-07-03 | 100             | 95

2. 각 항목에 대해 애플리케이션은 아래 조건을 검사한다.

if ((total_reserved + ${numberOfRoomsToReserve}) <= total_inventory)

모든 항목에 대해 조건이 True를 반환한다면, 날짜 범위 내의 각 날짜에 대해 객실이 충분하다는 뜻이다. 요구사항 중 하나는 10% 초과예약을 지원하는 것이다. 새로운 스키마에서는 이를 쉽게 구현할 수 있다.

if ((total_reserved + ${numberOfRoomsToReserve}) <= 110% * total_inventory)

이 시점에서 면접관은 후속 질문을 할 수 있습니다.
“예약 데이터가 단일 데이터베이스에 담기엔 너무 크다면 어떻게 하겠습니까?”

  • 현재 및 미래 예약 데이터만 저장한다.

    • 예약 이력은 자주 접근되지 않는다. 따라서 아카이브할 수 있고, 일부는 콜드 스토리지로 옮길 수도 있다.

  • 데이터베이스 샤딩.

    • 가장 빈번한 질의는 예약 생성 또는 이름으로 예약 조회다. 두 질의 모두 호텔을 먼저 선택해야 하므로 hotel_id는 좋은 샤딩 키다. 데이터는 hash(hotel_id) % number_of_servers 로 샤딩할 수 있다.


Concurrency Issue 동시성 이슈

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 실리콘밸리_생존자 · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture