List functional requirements for the system (Ask interviewer if stuck)...
List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
100 uploads per user per month
200 downloads per user per month
5 GB max file size
Average file size is 10 MB
UploadsPerSecond: 100 WPmonthPusers * 100,000 users= 10,000,000 W/month / 30 / 100,000 secondsPday = 3.33 WPS
downloadsPerSecond: 6.66 RPS
Define what APIs are expected from the system...
ID WriteFile(file, name)
File ReadFile(ID)
Status DeleteFile(ID)
Status ModifyFile(ID, new_file)
[File] SearchForFiles(string)
Can consider polling, long polling, SEE, etc.
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...
We agreed that eventual consistency is ok, we don't need ACID requirements, and with continuous data growth, could consider NoSQL in case of growth. Currently the WPS is low enough that SQL would probably be an ok option for some time.
A document or column oriented NoSQL DB would probably lend itself well here. Since users often open a page that contains their user information and files uploaded, maybe a document based DB makes more sense here than a NoSQL DB (which would be more optimized for cases where we only query for certain columns).
Storing file metadata within a user implies a 1:1 relationship between the file and user. This may not always be true down the road, what if a file could be owned by multiple users? This would imply we should actually have a separate table for files and then just have a list of file ID pointers in the users table. This is probably the better DB schema. Would look something like:
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design...
Load Balancer: A LB is probably not necessary for this design at all considering the WPS/RPS but considering there's consistent user growth, eventually it may be needed.
FrontendService: Handles all RPC requests.
MessageQueue: Allows synchronization of clients to happen asynchronously
ObjectStorage: Allows for durable object storage
Database: NoSQL DB that stores metadata for files stored for a particular user. Contains pointers to object storage for files.
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...
WriteFile:
Note: it's possible for a client to get out of sync with the service if we fail at step 4. Metadata will have been successfully written, but not sent to the sync service. We should have a polling system in the client to query for metadata state to catchup for failing cases here.
if step 3 fails, we could have data stored in object storage but no metadata attached. We should have a job that searches for these cases and garbage collects them.
ReadFile:
ModifyFile:
SearchFile:
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...
Performance Optimizations
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
Already addressed above, bottlenecks are likely in how data is replicated around the world and where the service is deployed.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?
We need logging in the frontend service for debugging
We need an analysis of the push pull model, how often do clients have to re-pull data and get out of sync. This can be done through metrics.
We need an analysis of how effective the caching mechanism introduced is.
We need an analysis of latency at various components to identify slow components, what if DB queries get slow, do we need to consider indexing on keys?