Since this is going to be a read heavy kind of system, we can assume that we are here having 100:1 read:write ratio.
Since we want read-operations to be of very low-latency, we can segregate read servers from write ones.
Assuming that we are having 1e7 DAU(for read operations). So read TPS would be around: 100, and since read/write ratio is 100:1, write TPS is 1TPS.
For saving images/multimedia, we would use S3
PS: I am using tweet and post words interchangibly.
Given the functional req., we could think of following APIs
We will be needing following Tables:
Api-gateway: It acts as authz/authn/reverse-proxy server, does throttling for us. We have added a LB in between feedService and api-gateway which helps in segregating read and servers in addition to consistent-hashing within a single type of servers.
FeedService: This service is responsible for showing the feed to the user, updating the feed for a particular user.
FollowService: This service is used to get the followers details, manager the followers list, update followers. Basically manage the lifecycle for connections service
ActivityService: This service is responsible for maintaining the activities performed on a particular tweet. Since this is a write heavy kind of service, we could leverage using a queue(kafka) to handle high volume of write requests.
RankingService: This service interacts with feed-service and performs a pre-defined ranking algo- to show what order the feeds should be shown to the user.
UserService: This maintains the life-cycle of user-profiles.
Api-gateway: It acts as authz/authn/reverse-proxy server, does throttling for us. We have added a LB in between feedService and api-gateway which helps in segregating read and servers in addition to consistent-hashing within a single type of servers.
FeedService: This service is responsible for showing the feed to the user, updating the feed for a particular user.
FollowService: This service is used to get the followers details, manager the followers list, update followers. Basically manage the lifecycle for connections service
ActivityService: This service is responsible for maintaining the activities performed on a particular tweet
RankingService: This service interacts with feed-service and performs a pre-defined ranking algo- to show what order the feeds should be shown to the user.
UserService: This maintains the life-cycle of user-profiles.
We are segregating read and write servers as read request call-volume would be a lot more as compared to write request.
Since, we want low-latency, especially for read-operations, we can pre-load the feed-to-be-shown to a specific(first 25 records) beforehand only. such that when customer comes online, it doesn't have to perform all the operations at that time. This would help in saving the latenty.
Also we could cache the feed-list for a particular user with some TTL, it is fine if a post is shown with some delay to the customer(after cache expiration), as we are fine with eventual consistency.
We need to emit metrics, have some canaries(imitating customers) running all the time to pre-detect the failure scenarios. We will have multiple replicas for each micro-service to avoid single point of failure and support high availability and fault-tolerance.
Our services interacts interally via means of Grpc clients with exponential back-off retry strategy in place..
We could have a few customer-imitating user-ids available which would fire calls and validate the outputs. These imitators we could use to create auto-cut tickets in case of any failure.
We will be emitting faults/error/P90 latency spike metrics and will have graphs/dashboards built over these(with alarm thresholds set) to pre-emptly catch any failure/fault/error.