List functional requirements for the system (Ask the chat bot for hints if stuck.)...
List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
Total number of users = 5 billion approx
Number of users logged in and viewing feeds = 100 million per second
Number of users posting = 10 million per second
Number of friends per user = 500 approx
This is a read-heavy system.
Define what APIs are expected from the system...
POST https://
json request
{
content:
share_with: public, friends, custom etc.
}
Response: post id, 201 created
GET https://
Array of JSON Responses:
{
postId:
postedBy:
content:
},
{
}
.....
Note: auth_token can be a JSON Web Token(JWT) to authorize and authenticate the request.
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...
Posts DB
========
Posts can be stored in either a SQL or NoSQL DB. Given the scale of a service like facebook and the amount of data, a document-store NoSQL DB like MongoDB is suitable.
Friends DB
=========
A graph-based database is suitable for storing friends graph and connections.
Memcached and Leaf Indexers
========================
In-memory caches used for fast retrieval
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. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
User: End-user who posts content and views the feeds.
API Gateway: Redirects user request to Post or Feed Service based on request type. Also responsible for authentication and authorization.
Feed Service: Responsible for servicing feeds for a user.
Post Service: Handles requests to post content and other user actions.
Memcached: Distributed cache with data of recent posts, friends etc.
Posts DB: Persistent store containing user posts. This can be a document store like MongoDB
Friends DB: Persistent store for friends data. This can be a graph-based DB
Notification Service: Service for notifying friends when a user posts new content.
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...
User: End-user who posts content and views the feeds.
API Gateway: Redirects user request to Post or Feed Service based on request type. Also responsible for authentication and authorization.
Feed Service: Responsible for servicing feeds for a user.
Post Service: Handles requests to post content and other user actions.
Memcached: Distributed cache with data of recent posts, friends etc.
Posts DB: Persistent store containing user posts. This can be a document store like MongoDB
Friends DB: Persistent store for friends data. This can be a graph-based DB
Notification Service: Service for notifying friends when a user posts new content.
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 design uses Fan-out-on-read or MultiFeed approach. In this approach, feeds are constructed when the user requests them. This is called pull-based approach.
Feed Service
=============
When a request reaches the Feed Service, it uses the Aggregators and Leaf Indexers to fetch the feeds.
Aggregators: Responsible for fetching the feeds to be displayed. It gets the feeds and sorts/filters them based on user preferences, relevance and other filters. Aggregator processes are CPU-intensive.
Leaf Indexers: Contain a map of posts per user. They use a hashmap where key is user id and value is a list of post ids. This data is kept in-memory. Leaf Indexers are memory-intensive.
Posts DB: Persistent Store for all posts
When Post ids are fetched, they are hydrated with actual content from the memcached cache and DB.
Posts Service
===============
All incoming posts are written to memcached, leaf indexers for fast access on reads and persisted in the DB.
Once a post is created, Posts Service invokes the Notification Service to notify friends of the user.
Static content is also updated in Content Distribution Network(CDN).
Explain any trade offs you have made and why you made certain tech choices...
Multifeed(Fan-Out-On-Read) vs Fan-Out-On-Write
=======================================
Multifeed constructs the feeds on a read-request(pull-based). This increases the latency on read but avoids write-amplification when a post is created. For example, if a user has 250 friends, the same post is written 250 times for the feed of each friend. Besides, some friends may not even view the post or are not online.
It also avoids the hot-key problem where a user can have more than average number of friends (for example, celebrities).
It also keeps the Feeds Service stateless.
Use Distributed Caching
====================
Memcached supports distributed caching and can scale horizontally
Use CDN for static content
====================
Publicly shared posts, photos and videos can be cached on CDN for fast access by users
Use JWT for Authentication and Authorization
===================================
Proven authentication and authorization technique which keeps Auth server stateless and thus allows horizontal scaling.
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?