Estimate the scale of the system you are going to design...
More read than write traffic: shortened URL gets generated once, but used many times
Say we make short URLs with 6 characters
There are 128 ascii characters-- round to 100
100^6 is 1,000,000,000,000 = 1 Trillion possibilities
URLs are up to 1,024 bytes -- 1KB
So we need to store about a petabyte of data
Short URL is www.sitename.com/<6 chars> -> about 20 characters
20 characters -> 20 B per URL -> 20 Terabytes
Dominated by the petabyte factor above
Honestly not sure what assumptions to make about usage
Info provided by coach: 10,000-20,000 redirect requests for each shortened URL
BUT traffic is not uniform-- likely will have some very hot URLs and many that are accessed infrequently if at all
shortenURL(URL) -> URL: generate shortened URL given regular URL
redirectURL(URL) -> URL: provide original URL given shortened URL
Key value store makes sense for this use case
We don't care about search/range queries, so we can use hashing to generate shortened URLs
Since we want high availability, we want replicas for fault tolerance
More read than write traffic, so single leader replication makes sense
How should the system handle a request for a URL it's already shortened? -> generate new short URL, to reduce the impact of hot keys
Access patterns suggest a cache would make sense -- generated URLs probably go stale and are rarely used after a while (say a couple months, generously)
See diagram
Read request:
Client -> Load balancing / reverse proxy -> Server -> Cache -> Database
Write request
Client -> Load balancing -> Webpage server -> database
Load balance using geohashing for low latency to cluster of servers
Then load balance within the cluster by range of the short URL hash to send request to server
Server checks its cache, and if that fails (cache miss), checks the database
When cache is full, evict least recently used (LRU)
For low latency, we should distribute clusters of servers globally -> geohashing for load distribution
Will need periodic sync between clusters to propagate newly written short URLs
Eventual consistency for this is probably OK
Could use change data capture to keep database replicas across geographically distributed clusters in sync
Since URLs will go stale, we want to cache commonly used short URLs. (Tradeoff: duplicating data)
Failure scenarios:
Trying to access a short URL that doesn't exist
Trying to access a short URL that exists but hasn't been replicated/propagated
Hot keys prevent nice distribution across servers
Hot keys: handle separately?