Architektura systemu rezerwacji biletów: od API do skalowania
System rezerwacji biletów musi zapewniać przeglądanie wydarzeń, wyszukiwanie według parametrów i niezawodną rezerwację bez podwójnej sprzedaży. Skupienie na dostępności danych przy odczycie i ścisłej spójności przy zapisie. Oczekiwane obciążenie — do 10 mln użytkowników na popularne wydarzenie, opóźnienie wyszukiwania poniżej 500 ms, stosunek odczytu do zapisu 100:1.
Kluczowe encje: Event (wydarzenie z datą, opisem, typem), User (użytkownik), Performer (wykonawca), Venue (miejsce z mapą miejsc), Ticket (bilet z miejscem, ceną, statusem), Booking (rezerwacja z listą biletów i statusem).
Projektowanie punktów końcowych API
API budowane jest wokół trzech priorytetowych funkcji. Zaczynamy od prostych punktów końcowych, doprecyzowując w trakcie projektowania.
Przeglądanie wydarzenia:
GET /events/:id -> Event & Venue & Performer & Ticket[]
Zwraca szczegóły wydarzenia, miejsca, wykonawcy i listę biletów do renderowania mapy miejsc na kliencie.
Wyszukiwanie:
GET /events/search?keyword={keyword}&start={start_date}&end={end_date}&pageSize={page_size}&page={page_number} -> Event[]
Filtrowanie według słów kluczowych, dat, paginacja dla wysokiej przepustowości.
Rezerwacja (wersja początkowa):
POST /bookings/:eventId -> bookingId
{
"ticketIds": string[],
"paymentDetails": ...
}
Później dzielimy na rezerwację i potwierdzenie dla niezawodności transakcyjnej.
Architektura wysokiego poziomu
Komponenty systemu
- API Gateway: routing, uwierzytelnianie, ograniczenie liczby żądań, logowanie.
- Event Service: odczyt danych o wydarzeniach, miejscach, wykonawcach z bazy danych.
- Search Service: przetwarzanie zapytań wyszukiwania z filtrowaniem.
- Booking Service: zarządzanie rezerwacją z transakcjami.
- Bazy danych: PostgreSQL dla transakcji ACID (Bookings, Tickets), NoSQL lub cache do odczytu (Events, Venues).
Przepływ przeglądania: klient → Gateway → Event Service → Baza danych → odpowiedź z mapą miejsc.
Skalowanie pod obciążenie
Dla 10 mln DAU na wydarzenie używamy:
- Cache'owanie: Redis do częstych odczytów (wydarzenia, wyszukiwanie).
- Sharding: według eventId w Tickets/Bookings.
- CQRS: rozdzielenie odczytu (repliki odczytu) i zapisu (master).
- Load Balancer: rozkład ruchu między serwisami.
Stosunek 100:1 odczyt/zapis dyktuje priorytet replik odczytu i CDN dla danych statycznych (mapy miejsc).
Szczegóły rezerwacji i spójność
Krytyczna strefa — unikanie podwójnej rezerwacji. PostgreSQL z transakcjami i izolacją Serializable lub Optimistic Concurrency Control (OCC) na wersji biletu.
Proces:
- Klient wybiera ticketIds.
- Booking Service rozpoczyna transakcję: SELECT FOR UPDATE na Tickets.
- Sprawdzenie statusu (available), aktualizacja do reserved.
- Utworzenie rekordu Booking.
- Potwierdzenie płatności → status confirmed.
Przykład tabeli Tickets:
| id | event_id | section | row | seat | price | status | version |
|----|----------|---------|-----|------|-------|--------|---------|
| 1 | 123 | A | 1 | 5 | 100 | available | 1 |
OCC: przy UPDATE sprawdzamy version, reject przy konflikcie.
Dla wysokiej konkurencji — tymczasowe rezerwy (TTL 10 min) w Redis.
Optymalizacja wyszukiwania
Podstawowy filtr SQL nie skaluje się do 10 mln. Przechodzimy do:
- Elasticsearch do wyszukiwania pełnotekstowego według keyword, performer, venue.
- Indeksowanie Events z polami: name, date_range, location.
- Wyszukiwanie fasetowe dla filtrów (data, typ).
Przepływ: Search Service → zapytanie ES → agregacja → cache w Redis.
Opóźnienie <500 ms osiągane jest przez wstępne ładowanie popularnych wydarzeń.
Zagłębienie w skalowalność
Bazy danych
- Master PostgreSQL (Bookings, Tickets) — shardowane według eventId.
- Read Replicas — 10+ dla przeglądania Events.
- Redis — sesje, tymczasowe rezerwy, top wydarzenia.
- Elasticsearch — wyszukiwanie, analityka.
Migracja danych: Event Service zapisuje do Kafka → CDC → repliki/ES.
Monitorowanie i odporność na awarie
- Circuit Breakers w serwisach.
- Health checks, auto-scaling.
- Backupy: WAL archiving w S3.
Co jest ważne
- Ścisła spójność tylko w transakcjach Booking, eventual consistency dla wyszukiwania.
- OCC + tymczasowe blokady w Redis zapobiegają 99% konfliktów bez blokad.
- CQRS/ES zapewniają <500 ms wyszukiwanie przy obciążeniu 100:1.
- Sharding według eventId skaluje do 10M+ DAU.
- API Gateway centralizuje security i throttling.
— Editorial Team
Brak komentarzy.