The core functionality of the system is relatively simple, so the primary concern for capacity will be related to the scalability of the number of users. For a URL shortening service, we can assume an average of 500,000 requests per day.
The APIs for this service will be as follows:
The database used for this service will be a relational SQL database which will contain two tables which we will call User and URL. In the User table, we will store unique user ID's and a column labeled timeout which will store a datetime to determine if they have made too many requests. In the URL table, each row will contain the new short URL, the long URL used to create it, the user ID associated with the user who requested the URL, the date created, and last accessed date.
The user will access the web service, and in doing so will be transferred through the load balancer to one of the available servers. After which, they will login so the service can retain the user ID used for API requests. When the user requests a shortened URL, the service will store the original URL in the database and return to the user a shortened version. If the user provides a shortened URL that was created by the service, the service will return the original long URL.
If a user attempts to shorten a URL for a long URL that already exists in the database, the service will simply return the previously shortened URL instead of storing a new short URL.
Regular batch jobs will also be ran every 10 minutes (periodic health checks) to determine if any URLs in the database have not been accessed for more than 3 days. If they haven't, they will be removed.
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...
A relational database was selected for this service since it allows us to maintain structured data, which allows us to look up specific information regarding user activity, for example if they have made a certain number of requests, or if we want to determine how old a request is.
If a user makes a large number of requests and there is no limitations set on the number of requests they're allowed, they could potentially overload the server.
Additionally, if 2 users attempt to shorten the same long URL at the same time, this could result in duplicate data.
Malicious users may attempt to send numerous back to back requests, overloading the servers.
To prevent excessive data from individual users, mitigating the number of active submissions from a single user in the database will prevent a single user overloading the service. For example, if a user requests more than 3 shortened URLs, the service will remove the oldest entry from the user and create a new entry for the new URL.
If 2 users attempt to shorten the same URL, we can simply use a deterministic algorithm to ensure that the shortened URL will result in the same value. So to prevent duplicate data, we will also perform regular database health checks in the system to remove any duplicate short URL entries.
To prevent malicious actors overloading the servers with numerous requests, when a request is made, if the user has more than 3 entries in the database, we will see how old the oldest request is. If it is within the past minute, we will timeout the user for 5 minutes before they can make another request to mitigate malicious actors. This will be using using the timeout column of the User table. If the users last timeout period is greater than 5 minutes, they can make a new request.