Functional:
Generate shortened url
Redirects shortened url
Non-Functional:
Availability
Scalability
fault-tolerant
Assuming DAU 10 million and each user will generate 1 url per day, that's 10 m urls per day.
Assume each url takes 100 bytes it will be 100 * 10m = 1000m bytes = 1 GB per day.
That's 365 GB per year.
We can use Amazon DynamoDB: A fully managed NoSQL database that can handle a large traffic volume, ideal for scalability and performance.
GenerateShortUrl - returns a shortened url based in input url.
RedirectShortUrl - redirects the shorten url to the original url.
Cassandra has certain operational overhead and we have no need for complex queries.
Given that storing url doesn't require complex relationship we can use a no sql key value store like dynamoDB.
{ "exampleofaveryveryveryverylongurl.com/test/1/2/3/4", "short.xyzab.com"}
We can employ two primary services.
One for url shortening service. This service will be responsible for shortening the url based on algorithm such as base62.
we can employ another service call redirect service. This service will be responsible for redirecting the url.
The reason for this separate is because this service would be read heavy and thus we should optimize this service for read.
user creates shorten url.
key value gets stored into the dynamo db.
user request shorten url.
redirect service redirect to original url.
Like mentioned earlier we will use base62 to hash the original URL + timestamp. However there might be cases of hash collision.
One way to fix this is by retrying until we no longer have a collision. Given write probably isn't as large as read I think this would be acceptable.
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?