1.checkin function, user input vehicle size and time slot and location, return spot number or empty
2.checkout function, user input vehicle plate number/ticket number, return balance
3.checkavailability function, user enter vehicle size and time slot, return back availability spot number
4.booking function, user enter vehicle size and time slot return spot number
5.extend session, user enter ticket number or plate number and extend for a time
1.low latency, our system should be low latency, user call our api should not wait long
2.fault tolenrance, if one host is down, our service should still maintain runnable,
3.consistency. we should not let 2 vehicle booking same spot conflict happen.
suppose we have 100 spot lot each lot has avg 10000 spot
check availability peak traffic 10000/s and 1000/s avg, checkin checkout extend, booking has peak 1000/s traffic and 100/s avg, then suppose each host can handle 1000 connections, then we need 10 host, and suppose for each checkin transaction, takes 100byte storage, then average we need 100Byte * 100/s * 3600*24 = 24*36 GB = 0.864 GB storage
1.boolean checkAvailability(lotid, vehiclesize, timeslot)
2.String checkin(lotid, vehiclesize, timeslot)
3.String checkinWithReservation(String ticketnumber);
4.bigdicimal checkout(String ticketnumber, String vehiclePlate);
5.boolean extendSpot(String ticketnumber, String vehiclePlate, long extendedTime)
we need our db transaction to be atomic and accuracy and we also need to support complex query so we choose relational db such as postgresql
erDiagram
vehicle {
vehiclenumber (PK)
owner
contactphone
username
password
}
spot {
lotid (PK)
spotnumber (PK)
size
}
booking {
ticketnumber (PK)
spotid (FK)
vehicleid (FK)
starttime
endtime
}
vehicle ||--o{ booking : "One-to-Many"
spot ||--o{ booking : "One-to-Many"
1.user send a checkin request with vehicle size and the time slot and the parking lot id, first the request go to the load balancer and api gateway and then a specific host and check the database if there are any available spot if yes then return the spot number with the ticket id. if there is no available spot then return to the customer with no availability message.
2.user enter the ticket id and vehicle plate number and first system will check the database to see if the ticket id match with the vehicle plate number, if doesn't match then exit immediately, otherwise system calculate the time and calculate the money and return back.
3.user enter the ticket id and vehicle plate number and the extended time slot, system first check if the ticket id match with the plate number if doesn't match then system will return error message, and exit, otherwise, check the database to see if the spot is available to be extended, if yes then continue and update the database table,
3.if transaction for any reason failed, we need to rollback and we use relational database it support session level transaction rollback to make sure the data consistency.
4.if a user login failed then we return 401 unauthorized.
5.when a user request, first it will go to the load balancer and load balancer will check the connection number and forward to a host, and then it will go through the api gateway and where it will check the bear token and do the authentication and chech the qps and if we want to throttle the request or not.
for the database part, when multiple user checkin with same vehicle size and time slot, we need to make sure our data consistency. therefore we can use lock mechanism,we can use read lock and write lock, if multiple user check the spot availability, then we use read lock so multiple user can read but for the write operation we need to use write lock to make sure only one user can write into the table at a time. For the user checkout process, we can use batch processing by using a threadpool since we don't care the sequence which job finish earlier or later.
also for database, since we use relational database, we can add index to those unique columns, we can also normalization table to put highly freq columns into a same table, we can also sharding our table to scale up.
for load balancer and api gateway, we can use api gateway to do authentication and authorization, and to prevent from single user or single ip abuse we can do throttling on ip and username.
also inorder to improve the read latency we can implement caching like redis to boost the speed of read operation.
if we want to add a caching it can make read operation faster but if a user check out and release a spot, we also need to update the caching in time so that to let next customer checkin, and this process requires more overhead and cost.
we choose relational database since our system need to support complex join and querys and also relational database is good at atomic consistency data, but relational database is usually slower than nosql and harder to change the schema and harder to scale up comparing to nosql. the reason why we want relational db is acid is highly needed for parking lot scenario cause we want to make sure data consistency and rollback function is also provided. also we need to do lots of complex join and query, which is suitable for relational database.
one failure scenarios is if a user check out and release a spot, since we want to use caching for a better read performance, after we updated the database table, we also need to update the cache, which requires more time, a user can got spot full message before the cache got updated.
since we use read locks and write locks for availablility checking and checkin, one scenerio is multiple users check availability and they all got 1 spot and only one user check in successful but when other user trying to checkin got error message spot no longer exists.
we can implement distributed caching to enhance the caching update
we can also implement distributed locking for user checkin