Estimate the scale of the system you are going to design...
DAU = 5 * 10 ^ 6
Request per day per user = 2
Request per second = 5 * 10 ^ 6 / 24 * 60 * 60 = 116
Link size = 100bytes
CLicks per day per link = 100
Amount of memory for links for a year = 116 * 60 * 60 * 24 * 365 * 100 = 3.4 GB
2 Functions:
1) POST shortUrl/v1, BODY: longURL, RETURN: shortURL, STATUS: REDIRECT
2) GET shortUrl/v1, REQUEST PARAM: shortURL, RETURN: longURL, STATUS: REDIRECT
class User{
+Int ID
+Int UserID
+String Name
+String HashedPassword
+String Email
+CreatedAt
}
class LinkEntry{
+ RecordID
+ UserID
+ EntryID
+int clickCount
+String shortURL
+String longURL
+CreatedAT
}
For POST
1) Clients request Load balancer IP from a DNS service
2) Load balancer redirects request to one of the app servers
3) App server either encodes the long url to short url or forwards request to an encoding service
4) Encoded URL is stored in cache (if it fits)
5) ENcoded URL is stored in the database
For Get
1) Clients request Load balancer IP from a DNS service
2) Load balancer redirects request to one of the app servers
3) App servers retrieves longURL from cache (if it exists)
4) App server retrieves longURL from database
Use md5 or base62 to encode the URL
If application servers can't handle the encoding we can use a separate encoding Service
Explain any trade offs you have made and why you made certain tech choices...
1) Load balancer failure: another replica takes it's turn
2) Application server fail: another replicate takes it's turn
3) if LinkDatabase master fails it's ReadReplica is promoted ot master
1) Scale database layer based on the number of links, shard it by shortUrlHash
2) Add global session management in applicaiton layer