Let's consider the following requirements
URLs per second: 100 * 1000000/10000 = 1000 URLs/sec (24 hr -> 86400 ~ 10K)
Write operations: 1000 URLs/sec
Read operations: 10 reads: 1 write -> 10,000 reads/sec
Storage:
This service will primarily have two APIs
301 response code means URL has been permanently moved to Long URL and browser will cache it, subsequent requests for the same URL will be redirected to Long URL by the browser itself.
302 response code means URL has been temporarily moved to Long URL and sebsequent requests will be sent to our service by browser. Since we're tracking analytics like click rates, we will stick to 302 response code.
Good choice for this usecase is NoSQL database. We're planning to use cassandra.
Two table will be created
We will create a hash for each long url and store the details in the first table and add another record in long_urls. Second table is for duplicate URLs check.
For hash we're choosing base62 encoding of long_url and hash length of 7 is enough to create 62^7 ~ 3 Trillion URLs.
When Client will make a request a loabalancer and it will get forwarded to one of the servers.
When client makes a request with long URL. Server will assign a key to the longurl and store it in the database. This key will be base62 encoded and return a short URL. The encoded URL will be stored in cache with some TTL asynchronously.
When client makes a request with short URL. Server will first check in cache and return long URL else it will fetch from DB, store it cache asynchronously and return the long URL.
We're using cache-aside pattern to store the data asynchronously
KGS is a single point of failure, We need to add a standby server for KGS for better availablity.
If URL is not present, we will return 404 NOT FOUND Error.
If load is huge, we need to manually scale the servers