1) 100000 initial passengers
2) 10000 initial drivers
3) 5% of total users is concurrent - (100000 + 10000) * 0.05
4) Initial 5 drive requests per drivers - 10000 * 5 = 50000 drive requests per day
5) User record is 1Kb
6) Ride hgistory record is 1MB
7) Peak requests is 20% of daily - (50000 * 0.2) = 10000 requests daily concurrent
Estimation:
1) Peak request/day = 10000 = 10000 / 24 * 60 * 60 = 0.11 RPS
2) With a total of 111000 users and 1Kb or data per user we have = 111000 * 1 * 365 / 1024 / 1024 = 38.87 GB of data needed per year for user
3) with a total of 50000 riders per day and 1MB of history per ride we have 50000 * 1 * 365 / 1024 / 1024 = 17.578 TB of data needed per year for rides
4) Having one server serve 1000 concurrent requests we need peak RPS / 1000 = 1 servers
5) WIth DB servers holding 1TB of data we need: total amount of data for users per year / 1TB = 1 servers for holding data
6) WIth DB servers holding 1TB of data we need: total amount of data for reides per year / 1TB = 18 servers for holding data
POST /auth
POST /user
POST /user/rate
DELETE /user
GET /user
POST /driver
POST /driver/rate
DELETE /driver
GET /driver
POST /ride/request
POST /ride/accept
POST /ride/reject
GET /ride/history
GET /ride/estimate
GET /ride/search
POST /ride/connect_realtime
GET /map
POST /ride/pay
GET /ride/pay/history
POST /sos
POST /notification/subscribe
Passenger : +int PassengerID INDEX FK
Passenger : +String Name
Passenger : +String Password
Passenger : +String Email INDEX
Passenger : +float Rating
Passenger : +DateTime CreatedAt INDEX
Driver <|-- DriversLicence
Driver <|-- DriversCar
Driver : +int DriverID INDEX FK
Driver : +int LicenceID FK
Driver : +int CarId FK
Driver : +String Name
Driver : +String Email INDEX
Driver : +float Rating
Driver : +DateTime CreatedAt INDEX
DriversCar : +int CarId FK
DriversCar : +String NumberPlate INDEX
DriversCar : +enum CarType (economy, premium, etc)
DriversCar : +DateTime LatestMaintenanceCheck INDEX
DriversCar : +enum EnvironmentCode
DriversLicence : +int LicenceID FK
DriversLicence : +bool Moped
DriversLicence : +bool Auto
DriversLicence : +bool Bus
DriversLicence : +bool Car
DriversLicence : +bool Motorcycle
DriversLicence : +Datetime ValidUntil INDEX
DriversFeedback <|-- Passenger
DriversFeedback <|-- Driver
DriversFeedback : +int DriverID FK
DriversFeedback : +int Passenger ID FK
DriversFeedback : +String Feedback
DriversFeedback : +DateTime CreatedAt INDEX
SosLog <|-- Passenger
SosLog <|-- Driver
SosLog : +int DriverID FK INDEX
SosLog : +int Passenger ID FK INDEX
SosLog : +String Reason
SosLog : +Enum SosType
PaymentType : +int PaymentId FK Index
PaymentType : +enum PaymentType (card, bank)
PaymentTransatcion <|-- Passenger
PaymentTransatcion <|-- Driver
PaymentTransatcion <|-- PaymentType
PaymentTransatcion <|-- PaymentTransatcionStatus
PaymentTransatcion : +int TransactionID FK Index
PaymentTransatcion : +int PassengerID FK
PaymentTransatcion : +int DriverId FK
PaymentTransatcion : +int PaymentType FK
PaymentTransatcion : +int StatusId FK
PaymentTransatcion : +int AccountNumber INDEX
PaymentTransatcion : +float amount
PaymentTransatcion : +DateTime TimeStamp FK Index
PaymentTransatcionStatus : +int StatusID
PaymentTransatcionStatus : +String Name
RideLog <|-- Passenger
RideLog <|-- Driver
RideLog <|-- PaymentType
RideLog <|-- PaymentTransatcion
RideLog : +int LogId INDEX
RideLog : +int PassengerId FK
RideLog : +int DriverID FK
RideLog : +int PaymentTransatcionID FK
RideLog : +Coordinates from
RideLog : +Coordinates to
RideLog : +DateTime PickupTime INDEX
RideLog : +DateTime DropoffTime
RideLog : +DateTime RideRequestTime
RideLog : +float paymentt
RideStatus <|-- PassengerId
RideStatus <|-- DriverID
RideStatus <|-- PaymentID
RideStatus : +int RideID INDEX
RideStatus : +int PassengerId FK
RideStatus : +int DriverID FK
RideStatus : +int PaymentID FK
RideStatus : +Coordinates from
RideStatus : +Coordinates to
RideStatus : +DateTime PickupTime INDEX
RideStatus : +int Status ID FK
RideStatusVariant : +int StatusId
RideStatusVariant : +int Name
GeoHashTranslationRecord : +String Address
GeoHashTranslationRecord : +float lat
GeoHashTranslationRecord : +float long
1) Client - a mobile app
2) Apit gateway - entry point of the system also includes a rate limiter and load balacner
3) MapCDN - a cdn service that servec precomputed map tiles for a mobile client to render
4) Traffic Service - as service that pulls real-time traffic updates to make adaptive location predictions
5)TrafficnOtificationservice - a source of real time traffic updates
6) Auth - authorization and authentication service
7) Notifications SErvice - service to send and receive verious forms of notificaitons int he sytem
8) Location service - returns a path to follow for the driver with time estimates and traffic and user adaptations
9) User service - manages passegner and drivers accounts
10) FeedbackSERvice - collects and stores feedback about the drivers
11) SimpleLocationService - estimates a simple route from to with time estimates without traffic
12) AdaptiveLocationService - takes input from SimpleLocationPlanner Service and adapts route and time according to raffic conditions and input from the user
13) Ride service - an API gateway for all things regarding rides
14) Payment service - manages payment for the rides
15) Payment processor - scales multiple playent operations and records payment transatcions
16) Payment backend - an entity that performs payemnt (3rd party or a Bank)
17)TransactionLogDB - a database of transactions
18) Shards - balances data and write load acrosss multiple db shards
19) Caches - quickly retrieves hot data
Account creation
1) User contancs api gateway to create an account
2) Api gateway forwards request to a free server with UserSErviceAPi
3) UserSErvice creates a new user and records it in db
4) UserSErvice returns success
GetRide flow:
1) User contact API gateway
2) APi gateway forwards request to AUth service
3) User passe AUth. Latest precomputed map is downloaded from MapCDN into useres mobile phone
4) Request is forwarded to RideService
5) RideService translates Users current location and requestes location into a lat/long forma to query the geohash DB
6) RideService contantcs simple location service to plan simple route without any considerations using user data
7) A simple route is creasted
8) Using AdaptiveRouteService an adaptive route is created from simple route using traffic data from TrafficService or User preferences
9) During the ride a user cna influence adap[tive route service by sending an appropriate request
10) A websocket connection is maintained by the user with the traffic service to notify of the real time traffic situation
11) At the end of the ride user contancs APi to pay for the rider and driver also contans api to update the stauts of the ride to finished
12) Paymen is submiotted to payment Service and transaction is recorded in paymanetDB
13) Ride status is logged in RidesDb to finalize the ride. Realtime ride updates are also recorded in RIdesDB
Ride Service consists of:
1) SimpleRdieService that builds a simple route without any traffic considerations using from to coordinates
2) GeoHash database that retrieves map graph data needed to construct the path from to by SimpleRideService
3) AdaptiveRideService that adjusts simple route based on traffic conditions and user input
4) TrafficNotificationService - that reads real-time traffic data and forwards it to AdaptiveRideService
5) ClientNotificationService - that accepts ride adjustments from the client
6) Ride log - records ride status when it ends + it records real-time updates due to traffic and user input
PaymentService
1) Payment service - accepts user requests for pasyments
2) Payment processor - scales multiple payment transactions for multiple users and records payment transctaion in transaction db
3) payment backend - issues the payment like a bank, 3rd party vendor and such
1) We use RabbitMQ or Kafka to scale our log writes to multiple Ride and Transaction shards as the number of writes can be become a bottleneck
2)To provide an in mmoery cache for geohash table we use in mmeory solution like redis. To not store an enormous amount of data for all roads on the planet we limit the zoom and distance for a client when one requests a ride
3) To have ap recomputed high definition map tiles we use a dedicated MapCDN with a predefined resolution and we also limit a client to not request more than agreed number of tiles and ride distances
4) To store UserData we use a simple SQL solution like MsSQL or t-SQL because the data is structured and the number of reads and writes is the same
5) for ride DB and transaction db we use a horizontally scaled db like Cassandra that is optimized for writes as those user flows are read heavy
6) To perform a quick search across our transaction and rides infor we can use ElasticSearch that is optimized for reads and search and is horizontally scalable
1) Too many requests for payment - we scale statelesss payment processors
2) Too many requests to write into transaction or ride DB - we use queue service like kafka or rabbit MQ + multiple DB sharded by transation or location ID to scale writes
3) Load balancer fails - we can have another on standby as they are stateless
4) Too many real time updates to rides - use multiple queue services like rabbit mq or kafka to provide scalable pub/sub model or use a dedicated VM like Erlang
5) When adaptive ride service fails while user is in transit users mobile app can predict the route based on GPS and the route already built
6) In the case of a low GPS signal a mobile client can fall back to a mobile Mesh network tower coordinate system
1) Use ML to make predictive route adjustments
2) Use block chain to secure transaction history and ride history
3) User ML to make predictive ride suggestions when traffic is expected to be heavy
4) Use ML to suggest places to visit when planning a route