Транспорт бэкенда
System Design: URL Shortener
bit.ly в 2009 году: 1 разработчик, 600M кликов в день, сервис не падает. Как? Правильная архитектура с первого раза: Redis для redirect cache, Kafka для async analytics, stateless приложение. URL Shortener - идеальная задача для system design интервью: простой продукт, но требует знания всего стека.
- **bit.ly** обрабатывает 600M кликов/день. Golang монорепо, Redis cluster для cache, MySQL шардированный для persistence. Real-time аналитика через internal streaming.
- **Twitter t.co** - URL shortener для всех твитов. Каждый URL в твите автоматически заменяется на t.co ссылку. 2B+ ссылок, используется для безопасности (malware scanning).
- **AWS CloudFront** CDN + Lambda@Edge: можно реализовать URL Shortener с latency < 5ms глобально - DynamoDB Global Tables + CloudFront без origin сервера.
Требования и оценки
Первый шаг system design - прояснить требования и сделать back-of-envelope расчёты. URL Shortener: bit.ly, tinyurl.com. Ключевые метрики: пишем редко (100 req/s), читаем часто (10K req/s). Read-heavy система 1:100.
bit.ly обрабатывает 600M кликов в день (~7000 req/s). tinyurl.com создаёт ~1M коротких URL в день. Правильная оценка масштаба помогает выбрать правильную архитектуру.
URL Shortener: Read:Write = 100:1. Это влияет на архитектуру как?
API Design
REST API для URL Shortener: минимальный и интуитивный интерфейс. Redirect - самый частый path, должен быть максимально простым. POST /shorten - создание, идемпотентный.
bit.ly использует 302 для всех redirect - они хотят считать каждый клик. Это добавляет ~10-20ms для запроса к серверу, но даёт полную аналитику. tinyurl.com использует 301 - быстрее, без аналитики.
Для URL Shortener с аналитикой кликов: 301 или 302 redirect?
Storage и Transport Layer
Read path оптимизируется через Redis: 115K redirect/s за счёт cache hit > 99%. Write path - PostgreSQL для durability. Генерация кода: hash от URL (MD5 первые 7 символов) или atomic counter с base62 encoding.
Cache hit rate 99% при Redis означает: из 115K redirect/s только 1150 идут в PostgreSQL. PostgreSQL с read replicas легко держит 1K-2K req/s. Без кэша - нужно было бы 50+ replica серверов.
Какой подход генерации URL кода лучший для production при 100M URL/day?
Асинхронная аналитика через Kafka
Аналитика кликов не должна замедлять redirect. Synchronous increment click_count в PostgreSQL при каждом redirect = O(115K writes/s) на горячую строку - lock contention убьёт производительность. Решение: async через Kafka.
ClickHouse - columnar DB идеальна для аналитики кликов: 1B rows/s insert, 100B rows/s query для aggregation. bit.ly использует внутреннюю аналитику с Kafka -> ClickHouse-подобной системой.
Почему synchronous UPDATE click_count при каждом redirect неприемлемо при 115K req/s?
Масштабирование и отказоустойчивость
URL Shortener - stateless application: любой инстанс может обработать любой запрос. Redis как shared state, PostgreSQL как source of truth. Geo-distribution для глобальной низкой latency.
bit.ly обслуживает 600M кликов/день с командой из ~50 инженеров. Архитектура: stateless Go сервисы + Redis cluster + MySQL (шардированный). Geographic distribution через CloudFront CDN.
System Design вопрос имеет одно правильное решение
System Design - это trade-off между consistency/availability/latency/cost. Разные бизнес-требования дают разные правильные архитектуры.
bit.ly и tinyurl.com решают похожую задачу разными архитектурами. Ключ: понять требования (аналитика нужна? глобальное распределение?), затем обосновать trade-off. Интервьюер оценивает reasoning, не ответ.
Geo-distribution URL Shortener: пользователь в EU создаёт URL, его читает пользователь в US. Как обеспечить availability если EU datacenter недоступен?
Итоги
- **Read:Write = 100:1** определяет архитектуру: Redis cache для redirect path, PostgreSQL для persistence. Cache hit > 99% = PostgreSQL читает < 1K req/s.
- **302 vs 301**: 302 для аналитики (каждый клик через сервер), 301 для максимальной скорости (браузер кэширует). Выбор влияет на всю аналитическую архитектуру.
- **Async analytics**: Kafka decouples redirect latency от click counting. Synchronous UPDATE горячей строки при 115K req/s = lock contention = деградация.
Связанные темы
URL Shortener применяет паттерны из всего курса:
- Kafka: producer и consumer — Kafka decouples redirect от analytics: click events -> Kafka -> ClickHouse без влияния на redirect latency
- Backpressure и Flow Control — Redis bounded cache (eviction policy) и Kafka consumer lag - backpressure механизмы в URL Shortener
Вопросы для размышления
- Как обработать vanity URLs (кастомные коды /my-brand) при существующем counter-based генераторе?
- Что произойдёт если Redis недоступен? Как деградировать gracefully без полного падения сервиса?
- Как добавить rate limiting для POST /shorten без влияния на redirect path?