1 to 1 user chat
group chat
High available that the app should always be available
High reliable that the msg should be persisted
DAU: 10M
Assume each user sends 100 messages per day
At peak time, we have 5x traffic
Peak QPS:
100 * 100M * 5 / 1 000 000 = 50k message / sec
Assume each msg is 100 bytes, then throughput is
50k * 100 / 1000 = 5kb/sec
Storage
5kb/sec * 1 000 000 = 5 GB /day
send_message(from_user_id, to_user_id, content)
send_group_message(from_user_id, channel_id, content)
get_channels(user_id)
get_message(user_id, receiver_id, message_type), message_type is in [DM or GroupMessage], receiver_id can be a group_id or user_id
User table:
user_id, name, status, created_timestamp, email
Friendship table (shard_key: user_id1):
user_id1, user_id2, created_timestamp, last_viewed_message_timestamp
we will create two entries for two entities in the same friendship. In this way we can easily get all friends for user_id1
last_viewed_message_timestamp is for easily polling the unread message for a user.
Group membership table:
group_id, user_id, join_date, role, last_viewed_message_timestamp
last_viewed_message_timestamp here is similar to the one in friendship table, so we can easily get the unread messages for a given user in a given group
DM Message table (key is message_id):
Message_id, sender_id, receiver_id, message_content, created_timestamp
Sharded_by sender_id and receiver_id
We can shard the message table by send_id and received_id, so all messages between same pair of receiver and sender will go into one shard. Easy for message look up, and the data should be evenly distributed
Group Message table (key is channel_id and message_id):
channel_id, message_id, sender_id, content, created_timestamp
Sharded by channel_id or channel_id and created_timestamp
We can firstly shard the group message table by channel_id, but if some channels are super hot, then we can further shard the table by using composite sharding key of channel_id and created_timestamp (with hour granularity)
After user login, it will firstly go through the Authentication and Authorization service. Then we have a session service that assigns a chat server to that user.
The user will communicate with the chat server through WebSocket.
The session service will also store the server and user mapping in DB, so we know how to send messages to a target user
Before message is delivered to a user, we can firstly store them in a queue.
In addition to deliver the message to users, we will have another service (message service) that stores those messages in the DB.
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...
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...
Explain any trade offs you have made and why you made certain tech choices...
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?