Estimate the scale of the system you are going to design...
Assume each user on average performs 5 fitness activties each day: with start time (8 bytes) , end time (8bytes), name (1024 chars* 1byte , notes ( 1024 chars * 1 byte ) = 2064 average bytes per day per user
With 1 millon users, an 1 year of trailing data, tthat give us: 701 GB of data
GPS data is composed of 3 numbers: lat, long, time stamp
WE can assume we record the coordinates every 30 seconds per user. if a user excesices 6o minutes per day on average that's 4*3*120 = 1440 bytes per user per day *365 = 489 GB
combined, that's 1191 GB of data a year for our Aurora DB to save. This should be acceptable.
fetch fitness data for user ( user, start,end)
getweightSessions?userUuid={uuid}&start={epoch_seconds}&end={epoch_seconds}
[{
{assoicated data in json}
}]
getDistanceSessions?userUuid={uuid}&start={epoch_seconds}&end={epoch_seconds}
[{
{assoicated data in json}
}]
publish fitness data for user
Post distanceSession/userUuid
publish weight lifting session data
Post weightLiftinSessiopn/uuiderUuid
DELETE distanceSession/userUuid
[
uuids
]
deleteWeightLiftingSesssion/useruuid
[
uuids
]
login
basic auth header returns JWT token with user uuid encoded in it
all other methods require JWT token with matching user uuid embeded in header to honor request
JWT token expires after 1 month
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
user
name ( string)
birthdate (datestamp)
distance session
uuid
type ( bike, run, walk)
GPS
parent distance_session_uuid
lat
long
timestamp
weight set
uuid
user_uuid
start_time- timestamp
resistance ( kg)
reps - count
weight set goal
uuid
user_uuid
targettime- timestamp
resistance ( kg)
reps - count
multiple clients will sync their local data stores with the server asynchronously. They will push out new data that's recorded on the device to the server while also querying the server for data that thye don't have locally.
WE'll use ECS to deploy the servers in behind a load balancer and auto scale the continer count by CPU usage.
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
1) user logs into device
2) device queries for all data for the user from the server
3) user adds new data recording to the device. Data is saved in device local db
4) devices sends the data to the server for backup / syncing
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
The local databases don't have scaling issues. The server is stateless and can scale up and down based on webtraffic.
The mysql server is only veritcally scalable, not horitonally, but it should be able ot handle a 1TB of data without issue. If scaling becomes an issue, we can shard the database so that the data is split across multple dbs as we don't need any cross user db access. We can apply modulo to user Id to determine coreect db for the account.
Explain any trade offs you have made and why you made certain tech choices...
First writing data locally, and then syncing it asyncronously will introduce replication delay. The advantage of this is we dont' have to worry about server side latency as this will be hidden from the user. The downside is that a user wil have to wait for their data to replicate to their other devices. For a fitness tracker application, this lag is acceptable because changin devices is often infrequent.
Try to discuss as many failure scenarios/bottlenecks as possible.
The device data store is wiped before the data can be replicated to the server - the data will be lost
The server is overloaded by requests, replication will take longer until the server can catch up.
The mysql db is lost -we'd hve to restore from a snapshot, some intermidate data could be lost, but it should resync from soruce devices if it's still there.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?