Should receive URLs and return a transformed, shortened URL, storing the original in a database
Receive user traffic via a shortened URL and redirect the user to the proper corresponding URL.
Delete dead links, meaning it should routinely ping existing links and delete key value pairs with dead URLS. Can also be done when a user submits a tiny URL
Should be fast and available, with re-directs taking very little time
Must be consistent, the same tiny URL should not go to more than one web-page.
Should be able to handle a large amount of user traffic at once
Estimate the scale of the system you are going to design...
Large scale, users from all over the world, millions of requests a Day
Expect there to be millions of Reads a day, but only thousands of writes
postURL(string realURL) - send a url to the server to be stored, return the altered URL.
getRealURL(string tinyURL) - request an actual URL, sending the corresponding shortened one
deleteURL(string tinyURL) - If after receiving the the real url, a redirect fails, the client informs the server that a url is dead. The server will then ping the url to check, and if it fails, the tinyURL and corresponding realURL are deleted.
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
Use a SQL database, storing the original and shortened URLs in Rows. If we want to allow for a many-to-one relationship between tiny URLS and Real Urls, we can normalize by putting real URLS in their own table.
If URLS have requests built into them, can store Request data in a JSON document within a column
Since we want the system to be available and consistent, should replicate our database with a multi-leader method of consensus, making reads quick. Do asynchronous updates to follower databases to avoid the leader from being overwhelmed.
Store URL parameters in the JSON since we don't need SQL features (wont index over them, nor join them)
Tiny URL ID | tinyURL | foreign key to real URL
real URL ID | real url base | JSON containing parameters
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...
Use a load-balancer to distribute client Read-requests across replicated follower nodes. A load-balance can also be used to send write requests to leader nodes.
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...
putURL requests flow to server carrying an original URL. The server will ping the URL to ensure that the URL is indeed alive. To get the tinyURL, hash the existing URL to a tiny one of a determined size. If there is a conflict, i.e. tiny URL is already used, increased the size of the expected tinyURL and hash again, repeat until there is no conflict.
Then store a row with a UUID, the tiny url, and the original url. then return the tiny url
On get requests, the server searches for the corresponding tiny URL. If found, grab the real URL and return it to the client.
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...
Servers hash the given URLs using a standard hash function, increasing the size of the output URL as conflicts occur.
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
Assume that two users try to write to two different URLs, and the URLs are hashed to the same result. A message queue with a single leader could ensure that the requests are granted sequentially. Additionally, writer locks could be added for whenever a hash is created, with the second request seeing this conflict and re-hashing.
In a multi-leader model, if the two users hash to different leaders, then they will both accepted and we have an inconsistency. We can record a time-stamp to choose the earlier one when consensus is reached, but some data will be clobbered.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?