Max capacity is 10,000.
Let's say that in peak hour we get around 8,000 cars.
10% of lots would be for trucks
25% - for motorcycles
65% - for cars.
Number of exits should be proportional to the number of available parking lots.
If we have 8000 cars in one hour.
One car takes 20 seconds to enter.
8000/60 = 133 cars arrive per minute
133 / 3 = 44 cars arrive per 20 seconds
So we need approximately 44 entrances.
For simplicity let's say that for exit we need the same time, so we need 44 exits as well.
POST
parkCar(type) - when the car tries to enter, system tries to park in the system, it gets the type of the car, looks at available slots, if it doesn't have any, returns an error response. Otherwise, returns the ticket.
POST
pay(ticketId, paymentType) - paying the ticket when exiting the parking. Returns receipt.
Database will be RDB, because we have structural data like parking type, ticket, car, receipt.
The car gets to the entrance, tries to get the ticket by providing the car type, the request goes to the application server, which gets the parking availability from the cache, in case there is no entry, gets the data from the DB and updates the cache afterwards.
The same flow is for checking out at the exit, but without using the cache, and checking the parking availability.
The space in the DB can be divided into car type + number of available slots.
LRU cache eviction policy works well here. But our cache won't be overflowed ever, because we don't need much data in there.
Cache can actually be stored in the application as a structure, because we don't store a lot of data in there.
We can replicate an application server to avoid SPOF. We don't need checkpointing because our server is stateless.
There is no much need of sharding the DB, due to low amount of data. But sync replication to a couple of nodes will work well to avoid SPOF.
We could be using a dedicated cache as a separate server, which would provide us decoupling, but it is not worth the effort and cost, as it can the data is small in case of the parking system, and we can easily reload it from the RDB.
Alternative to sync replication in the DB, would be async, which would speed up write requests, but in the parking system we highly value consistency over a little write latency.
In case all our application servers fail, we would lose the cache, as it is co-located with the application servers, but it would be pretty easy to restore it from the DB.
If we get to many cars at once at multiple entries, we will face latency in our system, due to sync replication.
Separate entrance from exit servers to separate the load.