Requirements
Functional Requirements:
- Allow users to tweet messages up to 140 characters.
- Enable users to follow other users.
- Allow users to like tweets from other users.
- Display tweets from followed users in the home feed.
- Show top K popular tweets in the home feed based on likes and followers.
Non-Functional Requirements:
- Multi Cluster
- Availability over consistency
- 10000 tweets/day
- 1:10 write/read ratio
- p99 latency - 1s
- 10,000 QPS
- Requires 99.999% uptime and no data loss
API Design
- /POST - post tweet
- /POST - load
- /activity - like or follow
- /POST - ingestion of tweets
High-Level Design
This problem requireds 2 micro serivce, one is loading home page and another to store user info and maintain it's social graph
Talking about first:
okay, going step by step on the API
- posting a tweet
- persist
- it should be a high available DB and durable
- Publish to other people feeds
- An async event to store this new tweet
- response back to customer
- success
- persist
- loading homepage
- get curated feed for user
- A read call to a pre computed queue assigned to the user at that time by some external system
- get curated feed for user
b. display topK
- ingestion - trigger to precompute the queue for the user
- queueEMptyEvent() or newFeedEvent() can be a trgger
- will get the feed ready for the user by some algo
- push into a queue in order of priority
- cache for sometime
Regarding NFR
- Assuming general request payload is , 4kb - so 10000*4 = 40 thousand kb - 500 KBps and same for response so, a total of 1000KBps or say 1 MBps -> any general ec2 can handle
- Read/write 1:10 so, so, write heavy db which can scale better with data
- keeping it multi clsuter behind an app gateway + elb (if any authz or authn or observability)
- metrics and alerts setup - any telemetry rool can help
- Multi cluster in differetn zones with each cluster is provisioned to handle 1.5x of the expected traffic
Talking about second:
- activity - like or follow
- both users Id, activityType, triggeredBy
- persist
- event to maintain user relations
Detailed Component Design
First microservice:
okay, so let;s setup schema real quick:
Tweet
a. tweetid
b. user
c. tweet text
d. ts.
Structure of messafge stored inthe queue
TweetId
Tweet metadata
targetUserId
priority
Audit table to store sent msgs or some metadata in the queue(if business asks for it) - future scope
Now, for 1st should be NoSql - since tweet can explode, need vertical scaling and new params can come
2 is just a java classm
Regd User Relations microserfice
- User table
- A neo4j db call to update user relations
Regarding the ingestion part:
this should be a cron job, every 5 mins or 10 mins (configurabel by the business based on user activity probably or whatever business want to track)
and can be triggered nefore as well in case of queue empty() event or fasterConsumption event
it will call the below microservice and get the nearest K users for the given user and get their top tweet from the tweet table and feed it to the queue.
for this queue i am thinking kafka (since i need ordering) for smaller usercase rabbit mq can be used but in long term kafka is better here
regd the infra setup, probably 6 (3+3) general purpose ec2 servers (hosting 3 microservices of homefeed and 3 of userRelations)
1 MYsql
! neo$j
1 nosql
1 Redis
1 Kafka setup
1 Classic Load balancer + api gateway
A CDN too if global customers
1 noSql