Reads:
If we are building a service similar to TinyURL, imagine we have 10M users that use it on average 5 times per day.
5 * 10M = 50M requests / day
50M / 24 / 60 / 60 = 580 QPS
Writes:
We expect this service to have a lot fewer requests made per second, let's say it's ten times fewer, 58 writes / second, 5M requests per day
Also, assume the system has 1B URLs stored, which is a fair assumption if 5M writes are made per day for 200 days.
set_alias(url: string, alias: string) -> error: set the alias of the url, return error if the operation cannot be done
go_url(alias: string) -> string: return the URL given the alias
We could use SQL database to store the URL data, as it is using B+ tree under-the-hood that optimizes for reads, which are satisfying our requirements.
In the flowchart I put Shard1 and Shard2, but it actually could scale horizontally based on the URLs added to the service. These shards could be placed at corresponding regions and AZs to improve the availability of the service and satisfy potentially country-based legislation requirements.
We also put LRU before our databse shard as there could be common hotspots when using the service. For instance go -> www.google.com could be a hotspot when using the service but a random document that shared between a private group might not be.
We want an alias to map to a unique URL, so alias is unique.
High level design of the system is shown in the flow chart. With load balancer doing the routing and authentication, and hashing service to generate the uid, handling collisions, and making sure the alias satisys the size requirement. Since we allowed user to set alias themsevles in our API design, this service doesn't need to generate a random unique string as alias but we can provide this as an option.
Database/Shards: Scale horizontally by adding more shards, scale vertically by adding more machines in each shard
LRU: LRU by its name is a least recently used cache. It's good for our use case to store some commonly used URLs to speed up query time
Hashing Service: It could be a single server as ~600 QPS is not a big load