DAU: 1M users; write 1 url/user on average, read 10 url/user on average
Read QPS: 1M * 10 / 10**5 = 100
Write QPS: 1M / 10**5 = 10
Read Peak QPS: ~300
Storage: 1M * 10 * 100B = 1MB per day, 365MB per year, 1.5T for 5 years
Read: GET /<short URL id>
Write: POST /api/shorten
User Table:
Short URL Table:
Several components:
Memcached for read operation enhancement.
The Lookup Service looks up whether a long URL exists in DB and will directly return the corresponded short URL to the user. If not, then insert a new long to short URL table entry and cache it aside.
The Redirection Service looks up whether the given short URL exists and will return the related long URL to the user. If not, throw an webpage error.
Same as above.
Each component contains several machines and are distributed. For example, Memcached, NoSQL database here are all distributed systems. This can prevent single point failure causing huge losses and multiple replica can help recover failed components.
The Lookup Service contains an short URL ID generator. We use Base62 as the encoding method. If a non-existed long URL comes, the system uses MD5 to encode (the long URL ++ the current time stamp). Since we want the short URL has a total of 7 characters, so in total this can represent 62**7 different short URLs. We convert the MD5 hex result to Base62 and only take the last 7 characters. If there exists such short URL already we retry the process.
When a request comes, there would be a load balancer first to balance the QPS and dispatch the QPS to different servers. Also in-between servers and Memcached/DB layers, we also need load balancers.