ticket system
Topic: ticket system
Interviewer: haha王国
Interviewee: 左茜
Level: L4 (Experienced Individual Contributor)
Topic
Mock System Design Interview Summary
Interview Overview
Date: 5/15/2022
Target level: L4
Duration: 45 minutes
Topic covered: Online ticket system
Drawing tool used: whimsical.com
Requirements
Functional requirements
Movie ticket system
Support different location
Movie, User, Cinema - Room, City
In each city there may be many cinemas
Payment
MovieTimeline
Non functional requirements
User amount: 1M visit per day
100K tickets per day
100 cinemas in total
More functional requirements
User login the website
User search movies in different ways
User can choose a movie and put it into cart
User chooses seats
Payment
Need to resolve conflict if 2 different users choose the same seat
Non functional requirements
Scale of the system. Scale fast within limited time
Optional
Get notification once there is a seat
1M / 24 / 3600 = 15 times/second
Peak traffic (popular movies, sold with 2 minutes)
100 * 200 / 120 = 200 times/second
4 + 1 = 5 machines
System Design
21:00
System architecture
Choosing sql vs no-sql.
Choosing mySQL: Low QPS, convenient to use
Add data balancer
Add cache to reduce read loads
Q: Searching for ticket vs ordering tickets. Should we have one service or two separate services?
A: need multiple services
Q: How to handle holding of ticket for 1 hour?
A: add column called hold_time, hold_Expire_time
User can choose a movie, put it into cart, hold the movie for 1 hour from database level, - unsold database subtract 1 from the table cron job
Data subtract 1 from the table
We need some API to finish the cronjob, e.g. checkAvailable(movieID, cityID, )
Alternative:
We don’t need cronjob
User A chooses a movie, and purchases the last ticket
User B chooses the same movie to purchase
Check the hold time of A. if it’s more than 1 hour, then user B can purchase the ticket
Q: Do you want to put all data in mysql?
A: yes. Unclear how to make it work across sql and noSQL
Q: if we increase the number of cinemas to 10,000, what do you need to do to scale
A: we can scale horizontally. Or we may use noSQL database.
Q: how to handle payment failures?
we received money but the ticket status may not have changed
A: use ACID protection. we received money, we need to refund money
Q: how to notify users when tickets previously unavailable becomes available again?
A: Email, SMS message
Q: what mechanism do we use to detect such situation?
A: we can use a scheduler
Q: Any additional improvements?
A: monitoring system for database, payment, and search.
For 2C system, we should track user behaviors; useful business information
Interviewer and Audience Feedback
Interviewer:
Overall is good. Can satisfy L4 requirements
Requirement gathering is clear
System design: I reduced the difficulty
System design: the drawing is not very clear in some area. Overall design is fine
Database choice is good
There can be improvement of detail area.
I wanted to discuss the DB schema design and tradeoff.
Interviewee:
The question is well chosen. It’s not a highly scalable system.
The data size is not very big.
OOD
Lots of details. I wasn’t able able describe things completely
We ran out of time for deep dive
I should add more details for scaling
===
Soft skill
Audience
Need to clarify requirement more
Too quickly jumped into OOD
Requirement -> resource -> data flow -> architecture -> scale up
Audience
Are the requirement too detailed?
A: about right
Similar to paper requirement. The time is insufficient for detail design
A: L4, we didn’t go into details
Hard skill
Interviewer
In the design of online resource, it’s split into multiple databases
Ticket database vs transaction database
Requires coordinator service
This may be too hard for L4
Movie database is good candidate for sharding, due to geography
Conflict resolution: add to cart and then put into hold
The best is to add lock during transaction.
What does coordinator service do?
All database needs to be reliable. Sometimes the money successfully was reduced but ticket is not reserved.
Go through a flow:
Choose a seat. Add lock to the seat
Send request to coordinator service. 2PC
Coordinator service send prepare for all databases. Databases send back ack.
Coordinator service send comment to all databases. Databases send back ack
Is retry required?
The most simple way is not to retry.
Why do we need to split into different databases?
If we use the same database for transaction and ticket
Since transaction needs to communicate with other external companies
Transaction DB relies on other companies
You can put in the same database, but it is harder to extend
I want to know available tickets
Ticket search service -> rename to movie search service
Why split into different DBs?
Reservation, ticket, etc.
Due to microservice architecture, each microservice need its own database backend
Why do we need to use microservice architecture?
It will be simple to use single service
Pessimistic or optimistic locking.
Big systems usually use microservice architecture
Regardless of whether to use microservice or single service, coordinator service is needed
2PC is not good
Should use saga
Coordinator service:
It’s better to use saga than 2PC
A ticket comes in, generates an ID
Payment is an external system; it can be very slow
Using 2PC you need to hold the transaction for a very long time
Payment succeeds: then we can proceed to the next step
Payment fails: then we can rollback
It’s better to use a local transaction.
To avoid clicking too fast, you can generate an ID for each user request
During payment and ticket reservation, we can use the same ID
Normally should use Saga not 2PC due to invoking external systems
If payment fails, the coordinator can rollback the original transaction.
Reason using saga: due to sequence in different actions.
Distributed transaction, 2PC, saga: saga orchestration, saga choreography
Reasons to use saga:
Payment service is invoked by API
The transaction is more suitable to saga, because it’s step-by-step
Internal transactions between 2 bank accounts, then use 2PC
If transaction between 2 banks, then use saga
Use seat to purchase. Should we have a queue for each seat?