Case Study 1: URL Shortener (TinyURL)
Hệ thống rút gọn URL, tương tự TinyURL, bit.ly.
Bước 1: Thu thập yêu cầu
Functional requirements
- Chuyển đổi URL dài thành URL ngắn.
- Redirect người dùng khi truy cập URL ngắn.
- Custom alias (optional).
- Analytics: số lần click, location, referrer (optional).
Non‑functional requirements
- High availability: URL luôn accessible.
- Low latency: Redirect < 100ms.
- Scalability: Hàng tỷ URLs.
- Durability: Dữ liệu không bị mất.
Scale estimation
- Users: 500 triệu URLs mới mỗi tháng.
- Redirects: 10 tỷ redirects mỗi tháng.
- Read/Write ratio: ~20:1 (nhiều reads hơn writes).
Bước 2: Ước lượng
Traffic estimates
- Create URL: 500M / (30 days * 24h * 3600s) ≈ 200 RPS (average).
- Redirect: 10B / (30 days * 24h * 3600s) ≈ 4,000 RPS (average).
- Peak RPS: ~10x average → 2,000 create RPS, 40,000 redirect RPS.
Storage estimates
- Data per URL: short_key (7 bytes) + original_url (500 bytes) + metadata (100 bytes) ≈ 600 bytes.
- Monthly storage: 500M * 600 bytes ≈ 300 GB.
- 5 years: 300 GB * 60 ≈ 18 TB.
Bandwidth estimates
- Upload: 200 RPS * 500 bytes ≈ 100 KB/s.
- Download: 4,000 RPS * 500 bytes ≈ 2 MB/s.
Bước 3: Thiết kế High‑Level
Components chính
┌──────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────┐
│ Client │ ──→ │ Load │ ──→ │ App Servers │ ──→ │ Database │
│ │ │ Balancer │ │ (Stateless) │ │ │
└──────────┘ └─────────────┘ └──────────────┘ └──────────┘
│ │
│ ▼
│ ┌──────────┐
└──────────────│ Cache │
│ (Redis) │
└──────────┘
Technology selection
- Load Balancer: NGINX hoặc AWS ELB.
- App Servers: Stateless, horizontal scaling.
- Database: NoSQL (Cassandra/DynamoDB) cho scale, hoặc SQL (PostgreSQL) với sharding.
- Cache: Redis cho frequently accessed URLs.
- Storage: 18 TB sau 5 năm → Distributed storage.
Bước 4: Thiết kế Chi tiết
Database Schema
Table: url_mappings
| Column | Type | Description |
|---|---|---|
| short_key | VARCHAR(7) | Primary key, unique |
| original_url | TEXT | URL gốc |
| user_id | BIGINT | Owner (optional) |
| created_at | TIMESTAMP | Thời gian tạo |
| click_count | BIGINT | Số lần click |
Encoding Strategy
Base62 Encoding (a-z, A-Z, 0-9):
- 62 characters, 7 characters → 62^7 ≈ 3.5 trillion combinations.
- Counter-based: Dùng auto-increment ID từ database, encode sang base62.
- Hash-based: MD5/SHA256 → take first 7 chars (collision handling needed).
API Design
POST /api/v1/shorten
{
"url": "https://example.com/very/long/url"
}
Response:
{
"short_key": "abc123",
"short_url": "https://tiny.url/abc123"
}
GET /abc123
→ 301 Redirect to original URL
Data Flow
Create URL:
- Client gửi URL dài → API.
- Generate unique ID (counter/hash).
- Encode ID → short_key.
- Lưu vào database + cache.
- Return short_url.
Redirect:
- Client request /abc123.
- Check cache → nếu có, redirect ngay.
- Nếu không có, query database.
- Lưu vào cache.
- 301 Redirect.
- Increment click_count (async).
Bước 5: Bottlenecks & Tối ưu
Single Point of Failure
- Database: Dùng replication (1 master, nhiều slaves).
- Cache: Redis cluster với sentinel.
- Load Balancer: Multiple instances với health checks.
Scalability Bottlenecks
- Database write: Sharding theo short_key hoặc user_id.
- Database read: Read replicas, cache hit rate > 90%.
- Counter service: Distributed ID generation (Twitter Snowflake).
Performance Optimization
- Cache strategy: Cache-aside cho redirects.
- CDN: Cache redirect responses cho static URLs.
- Async analytics: Dùng message queue để track clicks.
Bước 6: Trade‑offs
Consistency vs Availability
- AP system: Eventual consistency acceptable cho redirects.
- Cache có thể stale trong vài giây → user có thể thấy URL cũ.
Latency vs Throughput
- Low latency: Cache-first design, 301 redirect.
- High throughput: Async analytics processing.
Cost vs Performance
- Managed database (DynamoDB): Đắt hơn nhưng auto-scaling.
- Self-hosted (Cassandra): Rẻ hơn nhưng cần ops team.
Encoding: Counter vs Hash
| Approach | Pros | Cons |
|---|---|---|
| Counter | Unique, no collision | Predictable, need distributed counter |
| Hash | Non-predictable | Collision handling, longer storage |
Kết luận
Hệ thống URL shortener là bài toán cơ bản nhưng cover nhiều khía cạnh quan trọng:
- Encoding strategies cho short URLs.
- Cache design cho read-heavy workload.
- Database sharding cho scale.
- Async processing cho analytics.