(1) create a short URL from a long URL,
(2) redirect a short URL to its long URL
(1) low latency
(2) high availability
(3) horizontal scalability
(4) eventual consistency
(5) durability of mappings
apis:
/redirect?url=URL
/shorten?url=URL
Well, there is a main gateway which faces the client, gateway can be ratelimited but as ratelimit is not mentioned as non functional requirements we will leave it for now. so the requests something like /redirect?url=URL or /shorten?url=URL will go to gateway and gateway will make the request go the specific microservice.
there are 2 microservices with loadbalancers for horizontal scaling. one microservice is for shortening path i.e it will generate the unique url, and save it in the cache(lru) for idempotancy lookup and then write in write only cockroach DB. Then there is another microservice whose work is to check and redirect the client to the specific url. The microservice first check the cache(lfu based ttl) and then it goes to DB for checking wheather the db contains the certain url if not then it shows user wrong url or url not found. and if the db contains it redirects the user.
since we have atomic operations like saving in the db and also we have write heavy application (100:1) so i am going with the sql based db cockroach
DB.
FIrst lets deep drive to the load balancers, for horizontal scaling of microservices the loadbalancers are fixed so that microservices can be horizonally scaled which makes the design highly scalable and highly available.
secondly the read path is hot path so it contains a cache, which is Least Frequently Used based TTL so that the most hottest urls be there in the cache. it is because lets say some sunday morning one of the sites become viral due to a instagram video. so for that cache can handle that scenerio.
for achieving idempotancy, we have a cache in the path of url generator, to check wheather the uuid is present or not.
URL generation is based on
redis atomic counter
or distributed unique id
counter or snowflake (osp)
third is the seperation of read and write databases. and even in the read database there is consistent hashing so that we can scale horizontally pretty easily.