System requirements


Functional:

  1. User can view events and choose tickets with assigned seat
  2. User can search movies
  3. User can book ticket
  4. User can pay the ticket
  5. Admin can add events



Non-Functional:

  1. Latency should be low
  2. Weigh availability over consistency, but for reserving ticket and payment, keep high consistency
  3. Support 50K DAU




Capacity estimation

  • For booking ticket, we estimate each user books 2 ticket, so daily book request is 100K => QPS = 100 K / 3600 / 24 = 1.2
  • we assume each user has 5 search request and 10 viewing request, then the total read QPS = 15 * 50K / 3600 / 24 = 9
  • For storage, assuming we need 100 Byte for each seat info and related theater and movie info, then for one day the storage size is: 100 B * 100K = 10M, if we keep the information for 5 years, then total size: 10M * 365 * 5 = 19G, which should be easily handled by DB
  • Considering the QPS and we want to keep the system highly scalable, we'll design it as a distributed system



API design

  1. Search
  2. Get
  3. v1/search?query=xxx&user_id=yyy&page=zzz
  4. View event to detail description and seats distribution
  5. Get
  6. v1/event:even_id
  7. Reserve a ticket
  8. Post
  9. v1/reserve
  10. body {auth_token, user_id, ticket_id}
  11. Book a ticket
  12. Post
  13. v1/book
  14. body {auth_token, user_id, ticket_id, card_info}
  15. Admin update event
  16. Post
  17. v1/update/event
  18. body {event_name, description, theater_id, start_time, ticket_count}
  19. Admin update ticket
  20. Post
  21. v1/update/ticket
  22. body {ticket_list [{seat_no, price}, ...{seat_no, price}]}



Database design

  1. User table
  2. user_id
  3. user_name
  4. gender
  5. address
  6. email
  7. Event table
  8. event_id
  9. event_name
  10. description
  11. cdn_link
  12. theater_name
  13. screen_name
  14. start_time
  15. total_ticket_count
  16. remaining_ticket_count
  17. Ticket table
  18. ticket_id
  19. event_id
  20. start_time
  21. seat_number
  22. price
  23. status
  24. timestamp
  25. Search redis cache
  26. Key: Query
  27. Value: JSON event_list [{event_id, event_name, description, theater_name, screen_name, start_time, total_ticket_count, cdn_link}...]




High-level design

  1. User client - mobile/web
  2. User can search, view event and book ticket from the client
  3. Admin Client
  4. Admin uses the client to update event and ticket info
  5. Load balancer
  6. Responsible for distributing server request to server, we can use round-robin as the the load balancing algorithm
  7. API gateway / Webapp server
  8. Webapp server returns the web page to the user
  9. API gateway is responsible for routing different api request to corresponding service
  10. API gate is also responsible handle authentication check, rate limiting
  11. Search service
  12. Search service handle user's search request and build a search result event list as response to send back to the user
  13. Event service
  14. Event service handle user's even view request, getting ticket and seat information and send back to the user
  15. Event service also handle admin's request to update event and ticket via API v1/update/event, v1/update/ticket
  16. Booking service
  17. Booking service handle user's request to reserve ticket and handle book ticket by sending payment request to 3rd party payment service such as Stripe to finish booking
  18. 3rd party payment service
  19. In our flow, we rely on 3rd party payment service to handle the actual payment, Stripe is one of the popular payment service




Request flows

Searching

  1. User type a query from the client then search, it triggers API v1/search
  2. After the API is routed by load balancer and API gateway, the request is landed on one of search service server
  3. The search service first checks whether there's related events for the query from search cache, if not, then checks events in event table. Matched search results will be send back to the user. If there are pictures or media files related to the description of the event, user client will fetch them from CDN with CDN link from response data to reduce latency


Viewing

  1. User clicks a specific event from search result page
  2. The detail event page will be open with api call v1/event
  3. The page shows seats and tickets info for the event
  4. The v1/event request is handled by event service
  5. The service fetch event info from event table, and fetch ticket info from ticket table then return as response to render on the page


Booking

  1. There are 2 phase of booking: a. reserve the ticket, b. actual booking the ticket
  2. The reserve request is sent as api v1/reserve to booking service and update ticket data in ticket table. The actual booking is sent as api v1/booking to work with 3rd party payment service to finish booking. We'll discuss reserve and booking in more details in the detail design section.


Admin update

  1. Admin can update events and corresponding tickets from admin client with APIs v1/update/event, v1/update/ticket
  2. These APIs are handled by event service, new event will be added into event table, and new tickets will be added into ticket table




Detailed component design

Search

  1. Search DB
  2. We can start with using a SQL query to search related event in search DB. As the QPS and storage estimation we've done previously, it will work well for our current system. If we keep scaling the system, this can be a bottleneck, we can discuss further in the future improvement
  3. Search cache
  4. We use redis as search cache. The key is the query term and the value is a JSON list of events that matches the query. The redis cache can be maintained by daily job from search services to keep most frequently used queries and corresponding events in the cache. As building a search service can be another entire design topic to talk, we just keep the discussion at this level.
  5. Pagination
  6. In order to improve availability, reduce latency and provide better user experience. Pagination is supported for the search request. The page parameter in the request indicates which page should the search service return, we can set each page to return 30 results.


Booking & payment

  1. When user reserve a ticket, the booking service changes the status field in the ticket table to 'reserved' and update the timestamp, we consider the the reserve duration is 1 hour.
  2. When viewing the event by another user, the event service can check the timestamp and status, if the timestamp already passed 1hour duration, then the event service knows it's not reserved any longer and can return the ticket as available
  3. When handle the actual booking request, the booking service send an API request to the payment service, when the payment succeeded, the 3rd party service will send the success response as a registered callback to booking service. Then booking service can update ticket table to set status to 'booked' as well as update the timestamp




Trade offs/Tech choices

  1. Database selection
  2. The QPS and storage can be well handled by SQL DBs and we can easily support horizontal scale by sharding with event id
  3. Another reason we select SQL DB comparing to no SQL DB is that it's easier for us to update ticket status as it's table based
  4. In order to keep high availability we will have replication for userDB, eventDB and ticektDB with master-slave replication. Read request is handled by slave and write request is handled by master. For booking request as we want to keep strong consistency, during the book flow, ticket info read for corresponding ticket_id is blocked until the master finishes write and replicated the latest data to slaves





Failure scenarios/bottlenecks

  1. If search request failed, user will see empty search results, user can retry the search
  2. If booking failed, we need to ensure that the payment did not proceed for the user and return clear instructions to allow user to retry. The ticket status in ticket table should still be in reserved status




Future improvements

Search

  • To further increase search availability and reduce latency, we can integrate 3rd party search tech such as elastic search