System Design: Ticket Master

2. Design Ticket Master
Topics: High Contention
Ticketmaster is an online platform that allows users to purchase tickets for concerts, sports events, theater, and other live entertainment.
Functional Requirements ::3::
Features needed to satisfy the needs of the user.
In Scope
-
Users should be able to view events
-
Users should be able to search for events
-
Users should be able to book tickets to events
Out of Scope
-
Users should be able to view their booked events
-
Admins or event coordinators should be able to add events
-
Popular events should have a dynamic pricing
Non Functional Requirements ::4::
Specifications about how a system operates, rather than what tasks it performs. Defines system attributes like scalability, latency, security, availability, and are often framed as specific benchmarks. (e.g., system's ability to handle 100 million daily active users, response to queries within 200 milliseconds)
Benchmarks
-
The system should prioritize availability for searching & viewing events, but should prioritize consistency for booking events (no double booking)
-
The system should be scalable and able to handle high throughput in the form of popular events (10 million users, one event)
-
The system should have low latency search (< 500 ms)
-
The system is read heavy, and thus needs to be able to support high read throughput (100:1)
Out of Scope
-
The system should protect user data and adhere to GDPR
-
The system should be fault tolerant
-
The system should provide secure transactions for purchases
-
The system should be well tested and easy to deploy (CI/CD pipelines)
-
The system should have regular backups
Set Up
Entities
The core objects or concepts within a system which define its functionality and data.
- Event: record representing central point of info for each unique event
- User: represents individual interacting with system
- Performer: record of individual or group performing in event
- Venue: record of physical location where event is help
- Ticket: record of info related to individual tickets for events
- Booking: record of user's ticket purchase
API: the delivery framework ::3::
The contract between the client and the server and first point of reference in high level design. Usually map 1:1 with functional requirements.
- GET: Viewing info for specific event
A GET endpoint that intakes an eventId and returns details of that event.
// Get info for specific event
Request: GET/events/{eventId}
Response: HTTP/1.1 200
Body:
{
"eventInfo" : ...
}
- GET: Search parameters for list of matching events
A GET endpoint that intakes search parameters and returns list of events that match those parameters.
// Get info for events matching search parameters
Request: GET /events/search?keyword={keyword}&start={start_date}
&end={end_date}&pageSize={page_size}&page={page_number} -> Event[]
Response: HTTP/1.1 200
Body:
{
listOfEvents: [{}]
}
- POST: Booking ticket for specific event
A POST endpoint to intake a booking request.
POST /bookings/:eventId -> bookingId
{
"ticketIds": string[],
"paymentDetails": ...
}
Response: HTTP/1.1 201 Created
Body:
{
"ticketConfirmationInfo": ...
}
High Level Design Functional Requirement 1: Users should be able to view single events
Core Components
Core components high level:
-
Client: Users interact with system through web or mobile app
-
Load Balancer: Manages request loads from users by sending it to the instance of the API gateway with fewest connections at any given moment.
-
API Gateway: Entry point for clients to access different microservices. Responsible for routing requests to appropriate services, as well as authentication, rate limiting, and logging
-
Event Service: First Microservice responsible for handling view API requests by fetching event, venue, and performer info from the database
-
Events DB: Stores tables for events, performers, and venues.
GET Processing Steps
-
Client makes REST GET request with eventID
-
API gateway forwards the request to the Event Service
-
Event Service queries Events DB for event, venue, and performer information and returns it to the client
GET Diagram
User requests detail for an event():
GET/events/{eventId} -> Event
+--------+
Request: | Client | Response:
GET/events/{eventId} +--------+ HTTP 200:
^ {
| "event": ...
| }
| or
| HTTP 404 (resource not found)
| {
| "error": "..."
| }
V
+------------------+
| Load Balancer |
+------------------+
/ | \
/ | \
+------------------+
- Authentication | API Gateway |
- Rate Limiting +------------------+
- Routing ^
|
|
|
v
+------------------+
View(eventId): | Event Service | On Success:
1) QUERY short URL +------------------+ Return 200 Event obj
2) Redirect on match ^ On Failure:
| Return 404 (resource not found)
|
|
|
v
+-----------+
Event Table: | Database | Performer Table:
- Id +-----------+ - id
- venueId - ...
- performerId Venue Table:
- tickets[] - Id
- name - location
- description - seatMap
- ...
High Level Design Functional Requirement 2: Users should be able to search for events using parameters
Core Components
Core components high level:
-
Client: Users interact with system through web or mobile app
-
Load Balancer: Manages request loads from users by sending it to the instance of the API gateway with fewest connections at any given moment.
-
API Gateway: Entry point for clients to access different microservices. Responsible for routing requests to appropriate services, as well as authentication, rate limiting, and logging
-
Search Service: Second Microservice responsible for handling search API requests and querying database with parameters.
-
Events DB: Stores tables for events, performers, and venues.
GET Processing Steps
-
Client makes REST GET request with search parameters
-
Load balancer accepts request and routes it to API gateway with fewest current connections
-
API gateway then, after handling basic authentication and rate limiting, forwards the request to the Search Service
-
Search Service queries the Events DB for the events matching the search parameters and returns them to the client.
GET Diagram
User search events with parameters():
GET/search?term={term}&location={location}&type={type}&date={date} -> Partial<Event>[]
+--------+
Request: | Client | Response:
GET/events/{eventId} +--------+ HTTP 200:
^ {
| "events": []
| }
| or
| HTTP 200:
| {
| "events": empty
| }
v
+------------------+
| Load Balancer |
+------------------+
/ | \
/ | \
+------------------+
- Authentication | API Gateway |
- Rate Limiting +------------------+
- Routing ^ \
| \
| \
| \
v \
+------------------+ +------------------+. Query event Table directly for search
View(eventId): | Event Service | | Search Service |
1) QUERY short URL +------------------+ +------------------+ On Success:
2) Redirect on match ^ / Return 200 Partial<Event>[]
| / On Failure:
| / Return 200 Partial<Event>[]{empty}
| /
| /
v /
+-----------+
Event Table: | Database | Performer Table:
- Id +-----------+ - id
- venueId - ...
- performerId Venue Table:
- tickets[] - Id
- name - location
- description - seatMap
- ...
High Level Design Functional Requirement 3: Users should be able to book tickets to events
Core Components
Core components high level:
-
Client: Users interact with system through web or mobile app
-
API Gateway: Entry point for clients to access different microservices. Responsible for routing requests to appropriate services, as well as authentication, rate limiting, and logging
-
Booking Service: Third Microservice responsible for handling transactions with database, implementing proper isolation levels and either row locking or Optimistic Concurrency Control (OCC) to fully prevent double bookings.
-
Payment Processor: External service responsible for handling payment transactions. Once a payment is processed, it notifies our booking service of the transaction status.
-
Events DB: Stores tables for events, performers, venues, and now tickets and bookings.
GET Processing Steps
-
User is redirected to booking page/service where they can provide their payment details and confirm the booking.
-
Upon confirmation a POST request from the external payment service is sent to the /bookings endpoint with the selected tickets IDs
-
the booking server initiates a transaction to:
- confirm availability of selected tickets
- update status of selected tickets to 'booked'
- create a new booking record in the Bookings table
- If transaction is successful, the booking service returns a success response to the client. Otherwise, if the transaction failed because another user booked the ticket in the meantime, the server returns a failure response and we pass this information back to the client.
Note: When a new event is created, we need to create a new ticket for each seat in the venue, EAch of which will be available for purchase until it is booked.
Note: Fundamental issue where users can get to booking page, type in payment details, and find out ticket they wanted is no longer available. To be fixed in deep dive