System requirements
Functional:
- User Registration and Authentication: Users should be able to create accounts, log in, and manage their profiles.
- Search Functionality: Users should be able to search for movies based on criteria such as title, genre, or showtimes.
- Viewing Movie Details: Users should be able to see detailed information about a selected movie, including synopsis, cast, ratings, and available showtimes.
- Ticket Purchase: Users must be able to select the desired showtime, choose their seats, and complete the purchase of tickets.
- Payment Processing: The system should securely handle payment information, supporting multiple payment methods (credit/debit cards, PayPal, etc.).
- Booking Confirmation: After a successful transaction, users should receive a booking confirmation via email or SMS.
- Cancellation and Refund: Users should have the option to cancel their bookings within a specified timeframe and receive refunds accordingly.
- Admin Panel: Admins should be able to manage movie listings, showtimes, and handle reports/issues related to user accounts or transactions.
- Customer Support: Provide a help center or chat support for users to resolve issues related to bookings.
Non-Functional:
- Performance: The system should be capable of handling a minimum of 10,000 concurrent users without significant delays. Loading times for pages should not exceed 3 seconds.
- Scalability: The architecture should easily accommodate an increase in users and ticket sales, especially during peak times like holidays and movie releases.
- Reliability: The system should have an uptime of 99.9% to ensure users can access the platform reliably, even during high traffic periods.
- Security: Sensitive user data, including payment information, should be encrypted, and the platform must comply with standards like PCI-DSS for handling credit card transactions.
- Usability: The user interface should be intuitive and easy to navigate, allowing users to complete their tasks (e.g., searching for movies, purchasing tickets) with minimal effort.
- Accessibility: The platform should be accessible to users with disabilities and must comply with WCAG (Web Content Accessibility Guidelines).
- Maintainability: The system should be designed for easy updates and maintenance to minimize downtime during enhancements or bug fixes.
- Compatibility: The application should be compatible with various browsers (Chrome, Firefox, Safari) and mobile devices to maximize accessibility.
Capacity estimation
Initially 10000 concurrent users
Peak is 2 * concurrent = 20000 concrurrent
Total daily users 100000 users
A|verage ticket sales = 3 tickets per user per day
Data per account = 2MB
Data per ticket = 10KB
Estimated:
If we have 20000 concurrent users max we need: 20000 / 1000 = 20 servers to server requests
If we have 100000 daily users with 3 tickets per users it will be = 3 * 100000 / 24 * 60 * 60 = 3.47 QPS
Data to save yearly for accounts 100000 * 2 mb * 365 / 1024 / 1024 = 69 TB
Data to save yearly for tickets = 3.47 * 60 * 60 * 24 * 365 * 10kb / 1024 / 1024 = 1TB
Total data = 70TB, with 1 server holding 1TB we need 70 servers in total to hold data
With 20000 concurrent users and 1 server serving 1000 users we need 20 servers for connections
API design
POST /account
Post /login
get /account&account_id=
PATCH /account
GET /movies
GET /movie/ID/details
Get /movie/ID/seats
POST /book&cinema_id
POST /cancel&booking_id
POST /refund&booking_id
POST /support_ticket&booking_id
POST /new_movie
PATCH /movie/showtime
POST /movies/list
DELETE /account
POST /support_ticket/ID/resolve
POST /transaction/ID/rollback
GET /notifications/user_id
POST /movie/user_id/notify
POST /analytics
Database design
User : +int UserID PK
User : +String UserName
User : +String HashedPassword
User : +String Email INDEX
User : +DateTime CreatedAt
Admin : +int UserID PK
Admin : +String UserName
Admin : +String HashedPassword
Admin : +String Email INDEX
Admin : +DateTime CreatedAt
MovieTheatre : +int ThreaterId PK
MovieTheatre : +String Country INDEX
MovieTheatre : +String City INDEX
MovieTheatre : +String Street INDEX
MovieTheatre : +String PostCode INDEX
MovieTheatre : +DateTime OpeningTime
MovieTheatre : +float Rating
MovieTheatreMovies <|-- Movie
MovieTheatreMovies <|-- MovieTheatre
MovieTheatreMovies : +int FreeSspaceId PK
MovieTheatreMovies : +int ThreaterId FK
MovieTheatreMovies : +int MovieId FK
MovieTheatreMovies : +int FreeSeats
MovieTheatreMovies : +DateTime From
MovieTheatreMovies : +DateTime To
MovieTheatreMovies : +Enum Type
MovieReservation <|-- Movie
MovieReservation <|-- MovieTheatre
MovieReservation <|-- User
MovieReservation : +int ReservationID PK
MovieReservation : +int MovieTheaterId FK
MovieReservation : +int MovieId FK
MovieReservation : +int UserId FK
MovieReservation : +String SeatRow
MovieReservation : +int SeatNumber
MovieReservation : +DateTime ValidUntil
Movie : +int MovieId PK
Movie : +String Name INDEX
Movie : +Enum Genre
Movie : +Datetime CreatedWhen
Movie : +String JsonActorList
Notification <|-- User
Notification <|-- MovieReservation
Notification : +int NotificationID PK
Notification : +int UserID FK
Notification : +int MovieReservationID FK
Notification : +DateTime TimeStamps
Notification <|-- User
Notification <|-- MovieReservation
Transaction : +int TransactionId PK
Transaction : +int UserID FK
Transaction : +int MovieReservationID FK
Transaction : +int amount
Transaction : +Enum PaymentType
Transaction : +DateTime TimeStamps
High-level design
1) API gateway - a service to load balance HTTP requests to approapriate service. Alto acts as an AUth service
2) PaymentService - all things regarding payment like transcation acceptans, load balancing transaction processros and retrieving acks form transaction backend
3) Transaction processor a worker behind a transaction queu (to scale the load) which calls payment backend to issue the transaction, also accepts acks from transaction log
4) Ticket Service -- an aggreagate service regarding all things tickets and movie therethers
5) User service - all things regarding user management
6) MovieTHeater Service - all things regarding movie thethers like: search, update, find tickets
7) Rating service - a service to rate movie theters
8) BookingService - a service to book a ticket for a movie
9) MovietThetherCache - a cache with infromation regarding the most frequently acceseesd movie thetehers
10) DB layer - a long term DB persistence layer for all the movie theater data
11) Movie service - all things regarding movies like: search by genre, actors and such
12) NotificationSUbscribeService - a service that accepts user filters for movies to subscribe to. It reacts to an ew movies being update by cron job and sends notificaitons to users
Request flows
Book a ticket:
1) User issues an HTTP call to movie service to filter movies he wants
2) MoviesServiec queries cache for a filter. If cache has data the data is returned if not the service queries the DB layer
3) User issues an HTTP call to a movie thether service with newly returned movie ID to find a thether he wants to visit on specific dates
4) MoviesTheterServiec queries cache for a filter. If cache has data the data is returned if not the service queries the DB layer
5) User issues an HTTP call to a booking service to book a tciket with a movie theter id and movie id on specific date
6) The booking service blocks a ticket for a user
7) User contancts payment service to issue payment for the ticket
8) Payment service contancts payment backend for a payment and records transaction in the transaction log
9) WHen payment succeeeds the Booking Service returns ack for the user with a ticket id, records the booking in DB and records an action in the log
10) User now has a ticket
New ticket notification flow;
1)A backend cron job periodically COntancts MOvietheterService for a free tickets
2) A notificaiton is sen through a notification service to subscribed users
3) A user has a long pull connection with a notification service and is notified about new tickets
Detailed component design
1) Notification service consists of multiple topics and implements a pub/sub architecture where users subscribe to a certain sets of events
2) Booking service conflict resolution: when a user wants to book a ticket it might happen that his app will crash or send requests multiple times. To not book the ticket multiple times we create a unique order id sent to a user which he will use to book the ticket. If the user sends a different booking id the system will reject requets a duplicate.
3) Booking service multi user conflict resolution: when multiple users try to book the same ticket concurrently we might have a data race. To prevent i we can use pessimistic locking technique provided by the database (if it supports ACID properties discussed later) or we can use versioning (optimistic) locking if contention is not big
4) Movie and MOvie theater services have a background cron job that updates the database with the relevant infromation about new movies being released. After update the notification service informs subscribed users about new movies a potentially empty seats for a specific theter
5) Movie and movie theater DB is sharded by primary key and location to spread the load as the data can't fit in one server
6) Hot new movies have a ddedicated DB shards to handle traffic peaks
Trade offs/Tech choices
1) We shard our movie and movie theater DB by the following formula hash(id) % number of replicas to evenly distribute the data load among many servers
2) For our notification service we user apache Kafka that allows us easily distibtue the load of many pub/sub servers. We expect the number of notifications to be big in peak hours and this atchitecture suits us well
3) to store ticket booking and movie theater info we use an SQL solution because we want ACID properties when booking a ticket and we don't expect contention to be super heavy usually.
4) For high contention (during peak times or when a new movie is released) we use pessimistc locking and in the off hours we use optimistic locking (version based locking)
5)To store transaction log we user Cassandra which is optimized for writes as transaction log is append only database
6) To serve highly avaialble movie theather data in cache we use redis as a our memory cache which supports quick by key retrieval operations
7) To handle a huge amount of spike traffic we implement rate limiter in our API gateway to prevent system-wide outage. In the future to make system more avaialble we put queue front in front of our ticket booking servive and shard the load between multiple service booking instances to spread the load
8) To prevent users from booking a ticket to a show that is already underway we filter those shows based on the request arrival time and show it to the user in "greyed out" form
9) TO relax the previous assumption and allow the users to book tickets for a show in progress we can discard the previous filter and show a warning on a client app or a website
Failure scenarios/bottlenecks
1) All services and load balancers are stateless so any failures or load overcharge can be solved by spinning up another replica on standby
2) Failure in tnotification service can be fixed by spinnining up another machine to serve as a publisher of notifications
3) Cron job update failure can be detected by a dedicated heartbeat monitor, if heartbeat fails the service should be restarted
4) Any failure in transaction processor cna be solved by spinning up another processor as it is stateless
5) Failure in db shard replication can be solved with blocking user queries for a certain movie, thather until the dedicated replica is back up. To evenly spread the load when replicas dynamically enter or leave the system we can use consistent hashing schema
6) When we have al ot of contanetion when booking tickets we can switch from optimistic locking to psseimistic locking schema to reducae the number of retriees for db updates
Future improvements
1) User ML and add ML service to serve user suggestions regarding new movies
2) User ml and user location update to suggest popular thether weith new movies