Daily users: 1 million / day
Storage capacity: 1 url = 50 bytes average
1000 new urls a day = 50kb per day, 1.5 mb per month, lets say 100 mb per 5 years shall suffice
POST /alias [URL] -> {url: "http://url123", alias: "abcd"}
GET /alias/abcd -> {url: "http://url123", alias: "abcd"}
Only 3 components are required: Load balancer to distribute requests among instances, server instance, and a database.
No need to worry about concurrency because the server be stateless.
Caching can be done on Local Cache, no need to add distributed cache
SQL will be a good solution because our data is a relation by nature (relates URL and its alias), very natural
table alias{
id: long
url: varchar
alias: varchar
}
No need for microservice architecture. 1 monolith application is enough with 2 REST urls. Can be implemented as a Java Web application
Write path: client sends url -> url is verified as well-formed -> alias generated (next unique integer to base64) -> added to db -> returned to client
Read path: client sends alias -> url is retrieved from cache or DB -> returned
For alias, user can additionaly specify the expiration time, after which it will be removed from the database. Default: never expires.
Alias generation strategy: each ID will be generated from the table row's id (generated by the database), and then encoded as base 64. Database system will prevent collision because it will assign different IDs for different transactions.
There should be automatic horizontal scaling in case of viral link: new nodes will be added to handle high read. Only reading path is affected.
Caching strategy: Lazy Loading. In case of cache miss, URL will be loaded from the database by the alias and put into the cache (TTL 24 hours).
ID Generator outage should not happen because it is a part of a database system which is very reliable.