Functions requirements for URL service
List non-functional requirements for the system...
Assuming 100 Million urls are generated in a day
-> Write operation on the database = 100M/24/3600 = 1160
Now the nature of service is such that , reads will be more than write , let us assume that ratio is 10:1 for one write there will be 10 read operations
-> Read operation = 11600
Avg Len of URL = 100 Chars
1 URL needs = 100Bytes
one day storage requirement = 100 * 100M = 10GB
There are two major APIs to support
Input => Long URL
Output => Shortened URL
2 . GET - api/v1/shortUrl (This API is the redirection service that maps the shortened URL generated by POST request to long original url and redirects the user to the web page
Input => Shortened URL
Output => Long URL
As a starting nature of the data points to using a simple hashtable , but that is not practical for real time scnarios. We will use RDMS to store the Mappings , we will only focus on the data model of the core URL shortening service as of now. Lets name the table that we use to store the data as urls
Data Model -
shortened_url PK(primary key) - varchar
long_url - varchar
created_at - timestamp
expires_at - timestamp
user_id - varchar (optional if we track users to generate analytical services on top of URL shortener service)
shortened_url PK(primary key) - varchar this is chosen as primary key because access pattern is read by shortened url the get api which is read api as mentioned in Capacity estimation that reads to writes are 10:1 , get api needs shortened_url as the primary key.
We will start with a basic design and then deep - dive into the components critical to the system
Basic flow of the system is as follows
Let us assume the short URL looks like this: www.tinyurl.com/{hashValue}. To support the URL shortening use case, we must find a hash function fx that maps a long URL to the *hashValue*.
The hash function must satisfy the following requirements:
Hash function is used to hash a long URL to a short URL, also known as hashValue.
The hashValue consists of characters from [0-9, a-z, A-Z], containing 10 + 26 + 26 = 62 possible characters. To figure out the length of hashValue, find the smallest n such that 62^n ≥ 365 billion. The system must support up to 365 billion URLs based on the back of the envelope estimation. Table 1 shows the length of hashValue and the corresponding maximal number of URLs it can support.
To shorten a long URL, we should implement a hash function that hashes a long URL to a 7-character string. A straightforward solution is to use well-known hash functions like CRC32, MD5, or SHA-1. The following table compares the hash results after applying different hash functions on this URL:
Base conversion is another approach commonly used for URL shorteners. Base conversion helps to convert the same number between its different number representation systems. Base 62 conversion is used as there are 62 possible characters for hashValue. Let us use an example to explain how the conversion works: convert 1115710 to base 62 representation (1115710 represents 11157 in a base 10 system).
1. longURL is the input.
2. The system checks if the longURL is in the database.
3. If it is, it means the longURL was converted to shortURL before. In this case, fetch the shortURL from the database and return it to the client.
4. If not, the longURL is new. A new unique ID (primary key) Is generated by the unique ID generator.
5. Convert the ID to shortURL with base 62 conversion.
6. Create a new database row with the ID, shortURL, and longURL.
To make the flow easier to understand, let us look at a concrete example.
https://en.wikipedia.org/wiki/Systems_designThe flow of URL redirecting is summarized as follows:
1. A user clicks a short URL link: https://tinyurl.com/zn9edcu
2. The load balancer forwards the request to web servers.
3. If a shortURL is already in the cache, return the longURL directly.
4. If a shortURL is not in the cache, fetch the longURL from the database. If it is not in the database, it is likely a user entered an invalid shortURL.
5. The longURL is returned to the user.
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?