My Solution for Design an Efficient Parking Lot System with Score: 8/10

by dynamo_nectar738

System requirements


Functional:

  1. User should be able to make reservation to book the park lot if available
  2. User could get the park lot location and available in real time
  3. Each park lot has a detail information like space (large or small) for different cars. or if this park is for disabled individuals
  4. We should also highlight if this park has charge stations.
  5. We should allow user to book a park lot in advance.
  6. We should integrate with payment system to pay the parking fee
  7. User could cancel their parking if they could not arrive in time.
  8. We will keep the parking lot 15 minutes after the reservation time and cancel it automatically.
  9. User would get their notification if their reservation is success.


List functional requirements for the system (Ask the chat bot for hints if stuck.)...



Non-Functional:

List non-functional requirements for the system...

  1. System should be high availability
  2. System should handle the case of concurrent like different user book the same park lot in same time
  3. We should consider future growth of users and scalability
  4. We should keep our data security
  5. We should keep a low latency for book reservation and get the response of availability



  1. Let's assume the daily active user is 100000
  2. We assume only 80% of them will try to book a park, and all of them will get the park information at least 5 times.
  3. So the estimation write traffic would be 100000*0.8=80000 per day = 50 per minutes. and read traffic would be 100000*5 per day = 350 per minute = 6 per second
  4. Consider future growth, let's double the traffic, the write traffic would be 100 per minute = 2 per second. the read traffic would be 6*2=12 per second
  5. Consider there may be traffic spike in holiday, let's double again , so the peak write traffic in future would be 4 per second and read traffic would be 20 per second
  6. Let's go to the storage capacity, assume each reservation record cost 1KB, we take 4 record request per second , so daily record would be 24*4*3600*1KB=345MB, if we keep one replica, it should be 700MB, so yearly storage would be 700*365 = 255GB. we keep 4 year data retention for analysis, we need 1TB storage.


API design

  1. book a reservation
    1. POST /reservation/{user_id}/{park_lot_id}?start_time=${start}&end_time=${end}&type={type}
  2. cancel a reservation
    1. DELETE /reservation/{reservation_id}/
  3. Check available lots
    1. GET /reservation/{park_lot_id}/availability?start_time=${start}&end_time=${end}&type={type}
  4. Pay the parking fee
    1. POST /payment/{reservation_id}
  5. Get real-time available of parking lot
    1. GET /reservation/{park_lot_id}/start_time=${start}&end_time=${end}&type={type}
  6. Get detail information of a paring lot
    1. GET /park/{park_lot_id}
  7. Manage user's reservation
    1. GET /user/{user_id}?type=${type}




Database design

  1. User
    1. user_id PK
    2. user_name
    3. create_time
  2. Vehicle
    1. vehicle_id PK
    2. user_id FK
    3. vehicle_type enum
  3. Park_lot
    1. park_lot_id PK
    2. total_capacity
    3. small_size_park_capacity
    4. median_size_park_capacity
    5. large_size_park_capacity
    6. charge_station_park_capacity
    7. longitude
    8. latitude
    9. address
    10. status
  4. Reservation
    1. reservation_id PK
    2. user_id
    3. vehicle_id
    4. start_time
    5. end_time
    6. need_charge boolean
    7. reservation_status
    8. pay_status





High-level design

  1. App server
    1. user's side app to access our system
    2. server sider administration system to manage the park data
  2. API Gateway
    1. route traffic to different service and
    2. rate limitation
    3. audit log
  3. Reservation service
    1. To handle the request of add update or cancel the reservation
  4. Park-lot service
    1. To handle the add update request for park lot
    2. Return the real-time available information of park-lot
    3. To check if park lot have available lot for user


  1. Payment Service
    1. implement payment of user
  2. Notification Service
    1. push notification to user if his reservation finished
  3. Auth service
    1. authenticate user request to keep data security
  4. Feedback service
    1. collect user's feedback
  5. Loadbalance
    1. keep traffic balance in different server
  6. Cache
    1. cache data so give faster user experience
  7. DataBase
    1. store our data





Request flows

Reservation

  1. user request hit api-gateway and loadbalance, redirect to reservation service.
  2. reservation service will call park-lot service to check if available lot in this park-lot.
  3. if so, reservation service will create a record and save into db
  4. Then it will trigger a async task to notify user that his reservation is done
  5. If the reservation is not available, it will return a message to user to indicate have a retry
  6. If user cancel the reservation, it will update the status of record in database
  7. when user cancel the reservation advance, it will not charge fee, but if user does arrive in time and does not cancel the reservation, will call payment service to send a fee charge to user/


Payment

  1. When user's car arrive the park-lot, parking service will record this action and update the status of reservation
  2. when user leave, park-service will calculate the fee based on time and call payment service
  3. payment service will start a transaction ask user to pay




Detailed component design

Reservation Service

  1. our algorithm will allocate any lot exactly match user's requirement first, if it's available, we will create a reservation record.
  2. if there are no lot in match user's requirement but still other available lot, we will give a suggestion item to customer and give the decision to customer
  3. Conflict reservation: we will implement a optimistic lock mechanism to handler this case eg, if two user made reservation to same lot, then only one of them would successfully booked.


Cache

  1. To keep data consistent, after we update the record in database, then we update the corresponding item in cache
  2. For any GET request, it will hit cache and if no data existed in cache, then it would hit database.
  3. Each item in cache would have a expired time, and expired item would be evicted from Cache.
  4. We consider using redis as our cache layer
  5. When we update reservation record in DB, we will trigger a task immediately to update or add corresponding records in Cache to keep data consistent






Trade offs/Tech choices

Database

  • The biggest trade off here is using RDBS instead of NoSQL, because:
    • our payment service and book service has high requirement of transaction, eg ACID. this is a big pros of RDBS
    • our data capacity is not extremely huge so RDBS is okay to handle this
  • RDBS:
    • pros: ACID transaction guaranteed, strong consistency view of data
    • cons: we need to design our data schema carefully
  • NoSQL:
    • pros: data schema is flexible to change. more easy of horizontal flex up
    • cons: eventually consistency instead of strong consistency, NO ACID transaction





Failure scenarios/bottlenecks

Failure scenarios

  1. Concurrent reservation request
    1. Scenario that different user make a reservation to same park-lot and there is only one available park.
    2. one user would get the failure return information and he need to retry to make another request
  2. Notification service failed
    1. As our notification is an async task to give more faster user experience, but it may failed,


bottlenecks

  • In peak time, there may a large amount of user to book reservation , so the database performance would be a bottleneck
    • We could shard the database based on different country or location
    • We introduce a cache so the read traffic would hit cache first and it will return directly if cache hit







Future improvements

  • Notification service failed
    • We could have retry mechanism or has a message queue