My first time to try system design practice and I believe I will improve in the future! 7/10
by nebula4792
System requirements
Functional:
- allocate a parking lot in a duration
- exit
Non-Functional:
- geographical user friendly: find the available parking lot within shortest distance
- scalability but with strong consistency: the same parking lot can not be ordered by two customers
Capacity estimation
- User: 10 M
- Parking need: 1 time per user per day
- Network Traffic: since the whole parking process involves at 2 api calls: parking and exit, we can assume that there will be 2 write and 2 read for every parking. so the TPS and QPS can be: 10M * 2 / 3600 / 24 = 230
API design
- find available parking lot
- request
- user_id
- car_id
- location
- parking_start_time
- parking_duration
- response
- parking_lot_id
- location
- latitude
- longitude
- parking
- request
- user_id
- car_id
- parking_lot_id
- parking_start_time
- parking_duration
- response
- result: ok or not
- exit
- request
- user_id
- car_id
- parking_lot_id
- response
- result: ok or not
Database design
meta:
created_time int
updated_time int
deleted_time int
user:
user_id int
name string
email string
password string
last_login_time int
meta
car:
car_id int
owner_id int
car_type string ( different car may require different parking lot)
meta
parking_lot:
id int
location string
support_car_types []string
meta
parking_event:
id int
parking_lot_id int
car_id int
user_id int
start_time int
end_time int
duration int
meta
High-level design
- several stateless api servers to handle api call, can be scaled easily since they are stateless
- a load balance to route and balance traffic
- use mysql with replicas since it supports ACID
Request flows
- user call api and find available parking lots
- user call api to occupy the parking lot
- user call api to leave the parking lot
Detailed component design
- as the users grow, we need to scale our database as it is the destination of traffic
- to do the horizontal scale, we can consider shard database by region or user, then we can improve the write throughput
- we also need replicas to ensure availability
- the api server can be scale by deploying more servers since they are stateless
Trade offs/Tech choices
- we prefer consistency over availability as we don't want have such abnormal cases such as 2 users order the same parking spot. That means our services may experience unusable during issues like network partition
- we also sacrifice read throughput as all the read requests have to see the latest data so we can avoid stale data to misguide users
Failure scenarios/bottlenecks
- all read and write requests point to the leader database
- need to be aware of the isolation level of transaction, to avoid phantom reading
Future improvements
- use redis as cache to handle read request to check whether a parking spot is occupied. A simple string with expiration
- use distributed lock to avoid write contend