Design Uber

1. Introduction

Uber is primarily a ride hailing service. It is a platform to connect riders to drivers so that the riders can reach their destination. Some of other platforms providing similar services are Ola, Lyft, Gojek, Via, Grab and Bolt.

Prerequisites:

System design introduction : 3 principles of distributed system, 5 step guide for System design.

System design concepts & components : Horizontal scaling, Database, Caching, Message queues, Communication protocols

2. Requirement analysis 

Functional requirements

  1. Both drivers and riders should be able to continuously send out their current location
  2. Riders should be able to see the nearby cabs
  3. Riders should be able to book a cab. They should also be able to cancel a cab after booking but before boarding it.
  4. Drivers should be able to accept or reject the request for bookings.

Non-functional requirements

  1. The system should be reliable. It should always be up and running.
  2. The system should have high performance.

Additional requirements

  1. Our system should be able to suggest the shortest path for the trip.
  2. The trip should be completed after arriving at the destination.
  3. Our system should be able to accept payments.
  4. We should be able to save the trip information.
  5. We should be able to restrict the number of cancellations a user can make on a day.
  6. Our system should be able to implement surge pricing.
  7. The system should be consistent. A rider by mistake should not be able to do multiple bookings at the same time. Similarly the driver should not be able accept multiple bookings. Such scenarios should be taken care.
  8. Preferred Access points. The system should prompt for a preferred pickup location if it determines that it cannot come to the rider’s exact location.
  9. Our system should have the telemetry data to perform analytics.
  10. The drivers and riders should have ratings associated with them.
3. API design

Rider to system apis :

  • updateLocation(currentLocation)
  • searchCabs(userId, destination)
  • bookRide(userId, carType, destination)
  • cancelRide(userId)

Driver to system apis :

  • updateLocation(currentLocation)
  • acceptRide(userId)
  • rejectRide(userId)
  • cancelRide(userId)
  • completeTrip(userId)

System to rider apis :

  • showCabs(Map<CarType, Price> priceList)
  • bookingAcceptedNotification(DriverDetails, CarDetails)
  • rideCancelled()
  • retryAgainNotification(Message)

System to driver apis :

  • rideRequest()
  • rideCancelledNotification()

4. Define data model

We will not be defining the data model as we have clearly defined it as addition requirement to save the data.

5. Capacity estimations

Consider we have 10 Million bookings per day. Each booking will generate at an average of 2MB of data.

So per day we will generate
10 Million * 2 MB = 20 Million MB = 20,000,000 Mb = 20,000 GB = 20 TB of data.

6. High level design

Let us see a simple design for the given problem statement.

  1. The driver updates his location to the supply service.
  2. The supply service forwards the location data to the location service.
  3. The rider opens his app, sends his location and requests for a cab by sending a request to Demand service.
  4. The demand service sends the request to the location service.
  5. The location service responds with the nearby cab details.
  6. The supply service sends the cab details to the demand service.
  7. The demand service sends the cab details to the rider.

    What are the challenges we can see?

    1. The driver and rider have to update their current location continuously. We can use websockets for data transfer.
    2. We are bombarding our demand and supply service continuously with the location data say every second. We can introduce a queue like Kafka between the riders or drivers and demand supply services.

    How to maintain the location data?

    1. We draw a circle around our GPS location of radius say 1 KM and book the cab which is present in the 1 KM radius. It is a good but computationally costly solution
    2. Create grids which partition the area into several blocks. Which shape should we use to create the grid so that it covers the entire earth. We have choices of only 3 shapes triangle, square and hexagon.

    Existing libraries to maintain location data?

    1. Google’s S2 location library – Uses squares to create grid.
    2. Uber’s H3 library – Uses hexagons to create grid.

      Steps in updated design :

      1. The driver creates a WebSocket session and updates its location.
      2. The WebSocket service puts the location in the Kafka queue.
      3. This location is read by the supply service.
      4. The supply service sends this location to the location service. The location service maps the driver to the respective hexagon according to the location.
      5. The rider creates a WebSocket session, updates its location and request for a ride.
      6. The WebSocket service puts the location in the Kafka queue.
      7. The demand service reads the location from the Kafka queue.
      8. The demand service sends the data to location service.
      9. The location service maps the rider to the hexagon and finds the drivers in the neighboring hexagon and sends their data to the demand service.
      10. The demand service fixes a rider and sends the information to the notification service.
      11. The notification service sends a rideRequest to the driver.
      12. The driver chooses to accept or reject.
      13. A. If the driver rejects then the notification service informs this to demand service which finds a different driver.
        B. If the driver accepts then the notification service notifies the rider along with all the driver and car details. Parallelly the Driver gets the rider details.
      14. A. Suppose the driver chooses to cancel the ride after accepting it sends the message to notification service.
        B. The notification service informs the rider about the cancellation and sends a message saying that a new driver will be allocated.
        C. The notification service parallelly informs the Demand service about the cancellation so that the demand service chooses another driver for the trip.
      7. Scale the design

      We have 2 non-functional requirements.

      1. The system should be reliable. It should always be up and running – This can be accomplished using the no single point of failure principle. Here we add redundant copies of each of the components.

      2. The system should have high performance – This can be accomplished using the no bottleneck principle. We have to use Kafka queue and consistent hashing to divide the traffic.

      Scaling location service?

      RingPop design with SWIM protocol.

      8. Additional things
      Additional requirements
      1. Our system should be able to suggest the shortest path for the trip – Use Google maps API libraries which internally use Dijkstra’s Algorithm to find the shortest path.
      2. The trip should be completed after arriving at the destination – The driver will call an api informing the trip is completed.
      3. Our system should be able to accept payments – Have a payments service.
      4. We should be able to save the trip information – Use NoSQL database.
      5. We should be able to restrict the number of cancellations a user can make on a day – Use a rate limiter service.
      6. Our system should be able to implement surge pricing – We can create heatmaps based on the demand of cabs in a particular area.
      7. The system should be consistent – We need to use distributed locking to provide consistency. Reference link.
      8. Preferred Access points. The system should prompt for a preferred pickup location if it determines that it cannot come to the rider’s exact location –  This can be based on the trend of previous riders bookings.
      9. Our system should have the telemetry data to perform analytics – There are various data analytics tools like Hadoop, Spark which can be leveraged for this purpose.
      10. The drivers and riders should have ratings associated with them – Have a recommendation system.
      9. Next Steps
      Ask questions and share your feedback in the course.

      The Complete Design Interview Course

      Let's connect on LinkedIn

      © Copyright CompleteDesignInterviewCourse.com