My Solution for Designing a Simple URL Shortening Service: A TinyURL Approach with Score: 6/10
by whisper_ethereal162
System requirements
Functional:
- Create Short URL
- Redirect Short URL
Non-Functional:
- High availability 99.9%
- High RPS per redirect 20k
- 200 RPS creating
- Read-intensive system
- Very little response time for redirect 10ms, 5 sec for create
- Strong Consistency
- Monitoring
Capacity estimation
1000 symbols utf-16 = 2000 bytes
1 short link + 1 big link, aproxximately its 2kb for one link
200 rps per second = 2 kb * 200 = 400 kb per sec
400 kb * 86400 = 34.5 gb per day
34.5 tb per day * 365 = 12.5 tb per year, not a lot
12.5 * 5 = 60 tb for 5 years
API design
CreateLink(linkText)
- in: original link
ReadLink(shortLinkText)
- in: short link
Database design
It will be key-value database for speed of reading requests, I will chose Redis as most popular
Also I wanna use value optimization if we see a lost of simular values but I don't think people will have a lot of simular links
Database sharded for id to balance read and write requests, we need at least 10 shards to balance 20k read rps. Sharding using virtual buckets to be flexible adding new shards.
Master - master replicas for each shard
We use shards for balancing reading because if we use replicas there will be too many copies that leads to too many costs
Also we need have LFU key-value cache for this database for 1TB is ok
Database structure
key - short link - max 20 characters
value - original link - max 2000 characters
High-level design
Main thing is database
I mentioned design of it previously
We will have master-master replicas and lot of shard to handle such read rps
Url Creator Service will fill DB, Redirector will read DB. Redirector can't read links before Url Creator create it plus links are permanent so we dont need locks
Also we can have one slave DB for more accessibility
We have load balanced on top then API Gateway all with several instances to handle RPS
What about geo, we will have copy of our Server in each geo but sync their databases in master-master way. Long time write, but it is ok.
Url Creator will call Link Generator Service to general short link part
Generator will use fast encoding algorithm, let's take base64 for beginning
Generator will check for collision by accessing database and will use 2 instead of 1 random numbers based on time to handle collision and create unique link
Request flows
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...
Detailed component design
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...
Trade offs/Tech choices
We have long time write but have strong consistency, we are ok, we are read intensive
We have excessive caches and Databases for read optimization
Failure scenarios/bottlenecks
If any replica fails other is master master and will handle Critical time when we fix it
Also we can add one async slave replicas for each shard for more availability
Any of our Services use state in DB so they are stateless and we can easily multiple count of instances
Future improvements
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?