Lesson 1: Design a URL Shortener#
Goal: Design a service like TinyURL that takes a long URL and converts it into a short alias (e.g., http://tiny.url/xyz).
Requirements#
Functional#
shorten(long_url) -> short_urlredirect(short_url) -> long_url- Custom aliases (optional).
Non-Functional#
- Highly Available: If the service is down, URL redirection stops working.
- Low Latency: Redirection must happen in milliseconds.
- Read-Heavy: 100:1 read-to-write ratio.
Core Design#
1. Database Choice#
Since we need fast lookups and the data model is simple (Key-Value), a NoSQL Key-Value Store (like DynamoDB or Redis) is ideal.
- Key:
short_alias - Value:
long_url
2. Hashing Algorithm#
How do we generate the alias?
- MD5/SHA256: Too long.
- Base62 Encoding: Converts a unique ID (from a counter or database ID) into a string of characters [a-z, A-Z, 0-9].
🛠️ Sruja Perspective: Modeling the Flow#
We can use Sruja to model the system components and the user scenario for redirection.
architecture "URL Shortener" {
requirement R1 functional "Shorten long URL"
requirement R2 functional "Redirect short URL"
requirement R3 availability "High availability for redirects"
requirement R4 latency "Low latency (< 200ms)"
// Define the system boundary
system TinyURL "TinyURL Service" {
container WebServer "API Server" {
technology "Go"
scale {
min 3
max 20
metric "cpu > 70%"
}
}
datastore DB "UrlStore" {
technology "DynamoDB"
description "Stores mapping: short_alias -> long_url"
}
container Cache "Cache" {
technology "Redis"
description "Caches popular redirects"
}
WebServer -> Cache "Reads"
WebServer -> DB "Reads/Writes"
}
person User "User"
// Define the redirection scenario
scenario RedirectFlow "User clicks a short link" {
User -> WebServer "GET /xyz"
WebServer -> Cache "Check cache for 'xyz'"
Cache -> WebServer "Miss"
WebServer -> DB "Get long_url for 'xyz'"
DB -> WebServer "Return 'http://example.com'"
WebServer -> User "301 Redirect to 'http://example.com'"
}
}