1. Given a long URL, create an associated short URL.
2. Given a short URL, return the associated long URL.
Availability - This service has to be highly available. Especially functionality (2) (redirection).
Response time - Functionality (2) has to have low response time, e.g., less than 10ms. Functionality (1) (creating short URL) can takes more time - less than 10 seconds.
Scalability - We will get more and more requests to create short URLs, so the storage has to be highly scalable.
80 requests per second for functionality (1) (creating short URL).
8000 requests per second for functionality (2) (redirecting request with a short URL to long URL).
I assume the random portion of shortened URLs to be 8 characters.
I also assume long URLs are on average 100 characters.
Each long -> short URL conversion would include:
Each entry is 144 bytes.
Per day, the service would generate 80 * 60 * 60 * 24 ~ 7MB of data.
Within 2 years, it would generate 5GB of data.
str shortenURL(str long_url, user_ID, expiration_time=None): Takes a long URL and returns a short URL.
str redirectURL(str short_url): Takes a long URL and returns the associated long URL.
For the main storage, I believe a NoSQL database, for example MongoDB, would be a good choice, for its horizon scalability and fast response time. Because shortenURL() can take some time, the service can relax the consistency requirement. It can use eventual consistency model, as long as write is propagated to all the database replicas within a reasonable amount of time. After a short URL is created, it would be acceptable to take some time (e.g. < 10s) for it to be available for use by redirectURL() API.
The database would be:
This would allow potential new features, e.g., listing URLs by a user, or looking up short URL given a long URL.
Although Cassandra would provide more scalability than MongoDB, the flexibility in schema design and secondary indexes make MongoDB more suitable than Cassandra.
Because the data size is not huge (5GB in 2 years), relational DB can be used, too. RDB's strong consistency and rich query capability might be helpful. But a NoSQL DB would be a safer choice if the service were to grow exponentially in the future. MongoDB can be configured to provide consistency suitable for this service, e.g., acknowledge write has been propagated to all replicas.
One of the most important requirements is performance of redirectURL() endpoint. As such, a cache system, e.g., Redis, would be used to improve the read performance. This is particularly important as there will be some short URLs that are particularly popular.
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
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?